30

I've seen code like:

if (delegate != nil && [delegate respondsToSelector:@selector(doSomething)]) ...

But, sending a message to nil just returns nil (which evaluates to NO), so why not just do:

if ([delegate respondsToSelector:@selector(doSomething)]) ...

Is the former faster if delegate == nil? Either way, I prefer the latter cause it's less code.

And, less is better than more. Every Unix pro knows that.

ma11hew28
  • 121,420
  • 116
  • 450
  • 651
  • I tend to use the latter one, and also scan my code for unnecessary checks for nil. If nil doesn't hurt, don't check for it. If nil would be a programming mistake, don't check for it (maybe use an assertion instead). – Eiko Jun 25 '11 at 17:37

3 Answers3

24

objc_msgSend, the function used to send dynamic messages in Objective-C immediately checks the first argument (the message receiver) and returns if it == nil. Therefore, the only overhead of nil messaging is a dynamically-linked library function call, which is slightly more costly than an "intra-binary" function call. Overall, is one approach more efficient than the other? Compound conditional statements usually require additional branching, so the answer is indeterminable without looking at the code the compiler generates, but more importantly profiling the running program. Premature optimization is a Bad Thing™, but I congratulate you for actually considering efficiency and questioning "idioms" such as this.

Tim Sylvester
  • 22,897
  • 2
  • 80
  • 94
Coleman S
  • 488
  • 1
  • 4
  • 15
  • @MattDiPasquale please pick up his answer~ – user392412 Dec 19 '11 at 13:36
  • It'd be interesting if someone compiles two different versions and analyzes the generated assembly to see which is faster. :) – ma11hew28 Mar 14 '12 at 02:27
  • But doesn't the compiler have to evaluate the arguments to objc_msgSend first? Perhaps @selector(doSomething) doesn't take much time, but if there was more complex arguments i would think THOSE arguments would need to be evaluated first. If this were the case, doing the !=nil check in the expression does make sense. I personally always include !=nil for this reason (and because i switch between other langs a lot so like to see this everywhere :)). – mobob May 26 '13 at 16:21
5

You are correct. This is technically unnecessary overhead in Obj-C as any message sent to nil will return nil automatically. However, if you ignore the call to respondsToSelector: by first checking if it's nil, then you will skip the overhead of the respondsToSelector: call. So it would be faster, but by how much, I'm not sure.

hgwhittle
  • 9,316
  • 6
  • 48
  • 60
Percy
  • 1,037
  • 8
  • 7
-3

There's a syntactical issue here- if you're sending -respondsToSelector to a nil object, it will always return nil. This is why you would do such a thing.

Aditya Vaidyam
  • 6,259
  • 3
  • 24
  • 26