2

I'm looking at some old code, and seeing the following if statement:

if ([NSThread currentThread] != [NSThread mainThread])

I have a sneaking suspicion that this is not the same as

if (![[NSThread currentThread] isMainThread])

I'm suspicious because we are getting some crash reports (iOS 6 only) from the field that appear to be caused by code that needs to be run on the main thread that isn't. The code appears to be protected by the former if statement, but given the number of crashes we're seeing I'm not convinced.

Are the two if statements above equivalent, or is it possible the first will fail for some reason?

Mike
  • 1,112
  • 1
  • 13
  • 20
  • 1
    The best option would be to use the class method: `+[NSThread isMainThread]`. That's shorter and clearer than your code. – Nikolai Ruhe Jan 03 '13 at 15:44

2 Answers2

1

This may or may not be the same - the result of comparison of objects using != is often not documented. Since it's a direct pointer comparison, it will return true for the exact same object only, not in the case of logical equivalence. That's why you should always compare objects using their dedicated equality and comparison methods.

(Here, you have a real chance that they're the same, in case + [NSThread mainThread] is a singleton, but that's an implementation detail - you should not rely on it, even if it works/seems to work.)

  • But theoretically direct object comparison should be fine for what I'm doing, right? There is one and only one main thread, therefore if the current thread is the main thread, the memory address should be the same and pass the test. – Mike Jan 03 '13 at 15:36
  • 1
    @Mike No. *Practically* direct object comparison is probably fine. But *theoretically* it's broken since `+[NSThread currentThread]` is not documented to always return the same instance for the same thread. – Nikolai Ruhe Jan 03 '13 at 15:42
  • If there is a dedicated `isMainThread` you should use that, since it could be the case that different `NSThread` instances can represent the same underlying thread. That's probably not the case, but if they give you this method you should use it. – Mike Weller Jan 03 '13 at 15:42
  • @NikolaiRuhe can you explain that further? How could `[NSThread currentThread]` return a different instance of the same thread? Is it possible for a given thread to have multiple instances? I'm quite rusty on thread concepts. I have no doubt we _should_ be using `isMainThread`, but I'm trying to determine if this really has a chance of fixing a crash I can't reproduce. – Mike Jan 03 '13 at 15:47
1

How could [NSThread currentThread] return a different instance of the same thread?

The documentation does not guarantee that the returned NSThread instance is always the same. A hypothetical implementation could be:

+ (NSThread *)currentThread {
    return [[NSThread alloc] initWithPrivateIdentifier:pthread_self()];
}

It's not likely that the actual implementation works like this. My gut feeling even says it would be safe to compare for instance identity–but the documentation does not support this.

Is it possible for a given thread to have multiple instances?

The documentation does not state the opposite. So, yes, it's at least thinkable.

I'm trying to determine if this really has a chance of fixing a crash I can't reproduce.

Actually, in practice, I doubt that [NSThread currentThread] != [NSThread mainThread] is different from +[NSThread isMainThread], but that's only my feeling.

Nikolai Ruhe
  • 81,520
  • 17
  • 180
  • 200