01.02.2014 Views

Objective-C Fundamentals

Objective-C Fundamentals

Objective-C Fundamentals

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

64 CHAPTER 3 An introduction to objects<br />

3.4.3 Sending nonexistent messages<br />

With the message send concept, it’s possible to send an object a message that it may not<br />

be able to handle. Unlike in a language such as C++ where a method must be declared<br />

in order for it to be called, requesting that a message be sent is just that: a request.<br />

Because of <strong>Objective</strong>-C’s dynamic typing, there’s no guarantee that the recipient of<br />

a message will understand how to process it, and no check is made at compile time to<br />

ensure it exists. The following code snippet will successfully compile even though the<br />

NSString class doesn’t implement a method called mainBundle:<br />

NSString *myString = @"Hello World!";<br />

[myString mainBundle];<br />

The best that the <strong>Objective</strong>-C compiler can do in a situation like this is produce the<br />

following warning during compilation:<br />

'NSString' may not respond to '-mainBundle'<br />

You may be wondering why <strong>Objective</strong>-C produces only a warning when other languages<br />

are more heavy handed and produce a fatal error during compilation. The<br />

answer is that <strong>Objective</strong>-C allows objects to dynamically add and remove methods and<br />

also gives them an opportunity to process any unhandled messages. Consequently, the<br />

compiler can never really be sure that a particular object won’t respond to an arbitrary<br />

message without giving it a go at runtime.<br />

If you want to get rid of the compile-time warning, the easiest way is to change the<br />

variable’s data type to id:<br />

id myString = @"Hello World!";<br />

[myString mainBundle];<br />

Alternatively, you could use a typecast:<br />

NSString *myString = @"Hello World";<br />

[(id)myString mainBundle];<br />

Because the id data type can reference an object of any type, the compiler is more<br />

lenient with its warnings. If it didn’t make this concession, it would have to warn about<br />

every message sent to an object typed as id because this type doesn’t explicitly declare<br />

the existence of any methods to the compiler.<br />

It’s important to note that although all the code snippets in this section successfully<br />

compile, they will all fail at runtime because NSString doesn’t handle a message<br />

called mainBundle. If the target object doesn’t define a suitable method, the message<br />

will eventually be rejected, just as addressing an envelope to a nonexistent address will<br />

cause it to become undeliverable. You’ll most likely come across this situation when<br />

you see the following fatal error in the debugger:<br />

*** Terminating app due to uncaught exception 'NSInvalidArgumentException',<br />

reason: '*** -[NSCFString mainBundle]: unrecognized selector sent to<br />

instance 0x3b0a1e0'

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!