Question

What does Objective-C property get resolved to in runtime? Will calling [obj valueForKey:@"property"] always yield the same result?

e.g.

obj.property

Was it helpful?

Solution

First, note that obj.property is precisely the same as [obj property]. Dot syntax is just syntactic sugar. While there are some small run-time implementation details related to properties that are different than other methods, for the purposes of this discussion, think only in terms of "I have an ivar named _key and a method called -key." The fact that you created that ivar and method by declaring a property is irrelevant for valueForKey:.

valueForKey: is a method, and it can be overridden by a class to return whatever it likes. The default behavior is that valueForKey: will first look for a method whose name matches the key, and will return the result of that. In the vast majority of cases, this means that if you have a property, then valueForKey:@"property" will return the value of it.

The full search path for the default implementation of valueForKey: is explained in "Accessor Search Implementation Details", but here is the "short" version:

  • get<Key>, <key>, is<Key> (yes, the first place it looks is getKey, which is a little embarrassing because you should not prefix getters with get unless they return values by reference, but there you go; it is the first thing checked.)

  • countOf<Key>, objectIn<Key>AtIndex:, and <key>AtIndexes. If a legal combination of these are found, then an NSArray-like proxy object is returned.

  • countOf<Key>, enumeratorOf<Key>, and memberOf<Key>:. If all three are found, then an NSSet-like proxy object is returned.

  • If accessInstanceVariablesDirectly is YES (the default), then ivars are checked, named _<key>, _is<Key>, <key>, or is<Key>. Yes, this is a way to access an object's private ivars.

  • If everything else failed, then it calls valueForUndefinedKey:, which is free to return a result (and this is in fact a very useful thing to do if you want a generic key/value store).

But nine times out of ten, you're going to get the value of the method named <key>.

Side note: valueForKey: returns an object. If the return is a number-like scalar (including BOOL), it will return an NSNumber. Otherwise it will return an NSValue. There is some special handling for NSPoint, NSRange, NSRect, and NSSize (on Mac; on iOS, only NSRange is handled specially I believe).

OTHER TIPS

obj.property is the same as [obj property], not [obj valueForKey:@"property"];. The latter is part of a system called Key Value Coding that's separate from properties.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top