See Also
Variables in Objective-C
Last week we looked at declaring atomic and nonatomic properties. I promised to talk about writing a thread safe getter this week, but I'm pressed for time today so I'm going to shoe horn in another short topic instead.Variables in Objective-C
When you declare a property in a class, the getter has the same name as the property, while the setter is the capitalized property name with
set
prepended. For illustration, here is a User
class with a property named active
:@interface User : NSObject { BOOL active; } @property BOOL active; @end @implementation User @synthesize active; @endThe compiler will generate a getter method named
active
and a setter method named setActive
. Sometimes the default method names aren't exactly what you want; for instance, it's a common convention that getters for BOOL
properties be prefixed with is
. In the case of our User
class, we would like to have the getter named isActive
.The
@property
directive has two attributes to do just this: getter=name
and setter=name
. Just like the other attributes of @property
, getter
and setter
are placed in parentheses after the @property
directive and before the property type and name. So the active
property in our example would look like:@interface User : NSObject { BOOL active; } @property (getter=isActive) BOOL active; @end @implementation User @synthesize active; @endAnd usage the
active
property now looks like:// example use of isActive getter User *user = [[User alloc] init]; // getter/setter called as methods if ( ! [user isActive] ) { [user setActive:YES]; } // getter/setter called with dot syntax if (user.isActive) { user.active = NO; }We'll take a closer look at dot syntax in the near future, but basically when the compiler sees code like this:
if ( user.isActive ) { user.active = NO; }it translates it into this:
if ( [user isActive] ) { [user setActive:NO]; }Dot syntax is complementary to properties, but is separate and unaware of them. When translating a setter call in dot syntax to the corresponding method call, the compiler always looks for a method beginning with
set
. If you change your setter name to something different, you'll see a compiler error likeobject cannot be set - either readonly property or no setter foundor
request for member 'setter name' in something not a structure or unionif you call it using dot syntax. So if we rename the setter for the
active
property to makeActive
instead of the default setActive
:@interface User : NSObject { BOOL active; } @property (getter=isActive, setter=makeActive) BOOL active; @endthen using method call syntax, we can now do this:
if ( [user isActive] ) { [user makeActive:NO]; }but because the compiler expects setters to begin with
set
, using dot syntax generates an error:if (user.isActive) { user.makeActive = NO; // ERROR: request for member 'makeActive' // in something not a structure or union }In general you should follow the standard conventions and use the default getter and setter names; it's less work for you and your code is easier for others to understand.
Next week, we'll look at the thread safety of getters that return retained objects.
2 comments:
Great post!
Thanks a lot
Thanks! Glad you found it useful.
Post a Comment