2

Why do we have to manually check this every time we try to send a message to an object that might not respond to the message/selector? Why can't the language do the check for us every time a message is sent, or every time performSelector: or the variants of this message gets called. This would eliminate all crashes due to sending invalid messages.

Is it too inefficient to do this?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Popcorn
  • 5,188
  • 12
  • 54
  • 87
  • 1
    Closely related, possibly contains your answer: [Why is it that sending any selector to a Nil object does nothing, but sending an “invalid” selector to any NSObject raises an exception?](http://stackoverflow.com/q/11530133) – jscs May 21 '13 at 06:22
  • Imagine you called a method that doesn't exist for a class(as it doesn't confirm to a protocol) then your code will crash. So we need to check if that class responds to the method/selector. – Anoop Vaidya May 21 '13 at 06:23
  • 1
    @AnoopVaidya: I think it's clear that Popcorn knows that, but wants to understand _why_ that decision was made. – jscs May 21 '13 at 06:25
  • Thanks Josh, yes I am wondering why Apple decided to make this design decision, and it looks like there isn't really a satisfying answer based on that link. – Popcorn May 21 '13 at 06:28
  • The end of rob mayoff's answer seems like it answers this question pretty well to me. /me shrugs – jscs May 21 '13 at 06:30
  • @AnoopVaidya: "then your code will crash" Not necessarily. It goes into the message forwarding system. Your class can dynamically handle it. – newacct May 21 '13 at 19:38

1 Answers1

3

There are a few good reasons why every method call doesn't have a built-in check. First, it would be pretty inefficient. But more importantly, in most cases you should only be calling known methods so there is no need for a check.

But there are various reasons why we do want to check at runtime. Protocols with optional methods are a prime case. Working with different versions of the API is another common reason. New methods get added or removed over time.

We need to be able to tell the difference between a mistake and knowing that we are calling a method that may or may not exist. When it is a mistake, we want the failure and exception. When a method is optional, we need to do the runtime check so that the call can be skipped if it doesn't exist.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • 1
    All true, and a slightly more esoteric reason is that objects have other options beyond simply running a method when sent a message -- [forwarding and so on](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtForwarding.html%23//apple_ref/doc/uid/TP40008048-CH105-SW1). That possibility makes a compile-time `respondsToSelector:` kind of check pointless, and a dispatch-time check only slightly less so. – jscs May 21 '13 at 06:36