Objective-C properties and dynamic typing

If you started to write Objective-C codes in its early days, by now you will have rigid foundation in the nature of Objective-C. Therefore, you will think that you can send messages to an object of which type is referenced as id, if the actual object has the messages implemented whether they are declared in their header files or not.

Objc-C runtime doesn’t require to include declaration of messages always. Although it can be hidden to a caller, if messages are actually implemented, it can be called. Especially when the objects are referenced with id type, it works like magic. (ADDED : Be careful. Although you can send messages to an object referenced as id, don’t rely on data they return. About 5 years ago, I checked the GNU Objective-C compiler, actually just an extension to C, and found out that it was not always consistent about data returned by such message calling. ) But for being sure and to prevent any unwanted behavior or errors, you check the target object with respondsToSelector:

With that in mind, let’s take a look at this code.

- (IBAction)startFSEventGathering:(id)sender
{
	if( fsEventStream == nil )
	{
// 1. Will this work?
//		fsEventStream = [NSApp delegate].fsEventStream; //1.

// 2. Or this?
//		DirectoryWatchDogAppDelegate *appDelegate = [NSApp delegate];
//
//		fsEventStream = appDelegate.fsEventStream;
//
// 3. This works always.
		fsEventStream = [[NSApp delegate] fsEventStream];
	}

	FSEventStreamStart(fsEventStream);
}

In an application delegator class, DirectoryWatchDogAppDelegate, the fsEventStream is constructed as property.
Then, if it is synthesized, you will think that the accessor messages are to be created automatically.
So, calling with dot syntax will be same to the case 3.

Are you sure? Yes, conceptually.
Let’s try it to see if it is really true.

Will the 1 work?
No, because the return type is id and it doesn’t know whether it has a proper access method or not.
It seems to me that the property mechanism is different from dynamic typing and thus message calling from the nature of dynamic typing. I expected using dot syntax will be same to the case 3. But this case 1 didn’t work.

How about the case 2?
Yes, it works. It knows that the object is a type of DirectoryWatchDogAppDelegate.

How about the case 3?
Even though the returned delegate is not casted to DirectoryWatchDogAppDelegate, its fsEventStream accessor could be called.

This raises interesting question.
Objecitve-C is very dynamic language and can call any message even though those messages are not declared in its header if it the messages are actually defined.
So, without casting, the case 3 can work.

However, property doesn’t work like that, even though the Objective-C language reference says that it creates access messages when synthesized and uses them.

So, I think it is not an accurate explanation but a conceptual explanation.

3 responses to this post.

  1. 爀헉군의 생각…

    한구즐님 몇일 전에 하신 말씀이 이내용이지요?…

    Reply

  2. xcode 4.1 에서는 해당 코드가 빌드 자체가 안되는 것 같습니다. iOS라서 그런 것일지도 모르겠네요

    Reply

    • Posted by jongampark on October 4, 2011 at 6:47 AM

      예전에 4.x대에서 되었었는데, 이상하군요. 그때 4.0으로 했는지 4.1로 했는지 기억이…

      Reply

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: