سؤال

I was reading iOS Big Nerd Ranch book and one of the examples shows how to add observer to NSNotificaionCenter :

    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(orientationChanged:)
                                             name:UIDeviceOrientationDidChangeNotification
                                           object:[UIDevice currentDevice]];

Now in orientationChanged the orientation is retrieved from the object posted in NSNotification:

- (void)orientationChanged:(NSNotification *)note {
    NSLog(@"orientationChanged  %d", [[note object] orientation]);
 }

My confusion is on this line: [[note object] orientation]

NSNotification's object returns and id, so this means we don't know the type of the object is UIDevice at compile time. However we are able to access orientation from the returned object without error form the compiler. How does the compiler know that the object type is UIDevice and accessing orientation is acceptable ?

هل كانت مفيدة؟

المحلول

How does the compiler know the object type is UIDevice?

It doesn't.

It sees that it's id. The type id is the generic object type. Thus, the compiler accepts without an error if you send it any message. Even if you send a nonexistent one.

This is because Objective-C is a dynamic language. Method calls (message sends), binding, even types are inferred during runtime, by the Objective-C runtime library. If you send an object a message it doesn't implement ("respond to"), then instead of a compiler error, a runtime exception will be thrown.

By the way, messages to id are assumed to return either id (so at most pointer-sized values, such as most integers may safely be returned), or the compiler looks at all the available selector names on all classes and tries to match the type to one of the selectors it found in case it was indeed found.

نصائح أخرى

Messages in Objective-C are dynamically bound to method implementations at runtime, not compile time. If you try to send a message to an object that does not implement a method then it will throw an unrecognised selector sent to instance exception.

You can prevent this exception being thrown by asking an object if it responds to a selector by sending it the message "respondsToSelector:". If this method returns YES then you are safe to send it the message. This is common when implementing a delegate in a class as some of your methods in the protocol may be optional.

For more information on how Objective-C messaging works you can read the Apple Objective-C Runtime Programming Guide: https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtHowMessagingWorks.html#//apple_ref/doc/uid/TP40008048-CH104-SW1

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top