Objective-C: Properties, Setters and Dot Syntax

Thu, Jul 24

I’ve been ramping up on iPhone development, and with the NDA still in place (as far as I know), I haven’t been able to blog about what I’ve written/learned. And with that, it’s been quiet in here. Too get back into this, let’s continue to spend some more time on Objective-C…

The properties feature in Objective-C is your friend. Once you’ve written a few classes and manually wrote the accessors (getters and setters), you’ll quickly understand why properties are a good thing.

In addition to automatic creation of getters/setters, there is an option to use dot syntax in place of the traditional [receiver message] format.

I want to point out one little nuance when working with properties, setters and dot syntax , that I didn’t find to be particularly intuitive.

Let’s say you have a class with an interface definition such as this:

@interface SomeClass : NSObject
{
  NSString *str;
  NSDate *date;
} 

@property (nonatomic, retain) NSString *str;
@property (nonatomic, retain) NSDate *date;
...

The implementation file might look like this:

@implementation SomeClass

@synthesize str;
@synthesize date;

...

Using this approach, with the combination of @property and @synthesize, we now have getters/setters that are automagically created for you. You can call them as expected

// Call the getter
NSLog(@"The value is: %s", [ptr str]);

// Call the setter
[ptr setStr:@"fubar"];

Using dot syntax, here is what a call to the getter would look like:

// Call the getter
NSLog(@"The value is: %@", ptr.str);

This syntactic sugar is quite handy and easy to grasp, for the most part (even more so if you come from languages such as Java).

Everything is pretty much as expected up to this point. The whole reason for this tip is to callout the syntax for the setter when using dot syntax. Logic tells me, it should look as follows:

// Call the setter, well on second thought, maybe not
ptr.setStr = @"Testing this";

Seems reasonable doesn’t it? It effectively matches the setter method of the [receiver message] approach. However, the correct syntax is:

// Call the setter
ptr.str = @"Testing this";

The first time I ran across a setter used this way I stopped, scratched my head a few times, scrunched up my face and probably mumbled something along the lines of "what the…"

As you dig deeper into Objective-C, and even more so, as you look into the examples that are included with the iPhone SDK, you’ll want to make note of this, as properties are used extensively throughout the code.

The format (for the setter) when using dot syntax takes some getting used to. However, hopefully this little tip will clear up the confusion until you are used to seeing this style of setter.

5 comments

Actually this way of setting seems more obvious. It basically mimics the setting of method variables.

foo = @”Foo”;
bar.foo = @”Foo”;

You could say that you “scope” your setting to the “thing” on the left side of the dot.

I’ve been using many languages (java, c#, ruby) and just started learning Objective C. To me this way of setting and getting methods seems more natural.

by Bertg on Jul 24, 2008. #

I don’t disagree. My comment is more about how getters and setters work in Objective-C when not using properties and how moving to using properties requires some rewiring on how you think about accessors.

When *not* using properties, a best practice is that getter methods are simply the name of the instance variable (i.e. name versus getName), whereas a setter method pre-pends ‘set’ to the instance variable name (i.e. setName). Therefore, calling the getter looks like this [someObject name] and calling the setter [someObject setName:@"foo"].

However, when using properties and dot syntax, the practice of pre-pending ‘set’ to the instance variable names no longer applies.

I can understand why the implementation works as it does (and your comment as well). If nothing else I point this out for those who are new to Objective-C, as I am. To understand how getters/setters work (and appreciate the value-add of properties), I started by writing my own accessors. Once making the move to use properties, it simply takes a little getting used to when you are expecting setters to have the format ‘setInstanceVar’.

by john on Jul 24, 2008. #

One thing to remember is the dot syntax based on how the @synthesize directive is declared.

@interface Foo : NSObject {
NSString *str;
}
@property(assign, readwrite) NSString *str;
@end

@implementation Foo
@synthesize name = str;
- (void) test {
self.str = @”hi”; // direct assignment to variable
self.name = @”hi”; // assignment through setter
[self setName: @"hi"]; // assignment through setter
}

The @synthesize directive generates the getter and setter functions, but also declare the name of the variable for the dot syntax. Thus “name” is an alias for the getter/setter even though the member variable is “str”. This becomes more important if you use the @property(retain,…) attribute:
@property (retain,readwrite) NSString *str;

self.str = @”hi”; // direct assignment to variable
self.name = @”hi”; // retained through setter
So while @synthesize does generate getter/setters using the Key-Value Coding rules, the dot syntax maps directly to the @synthesize name. I find this a nice enhancement to the language.

by stevebert on Jul 24, 2008. #

It’s also worthwhile to point out that using the dot syntax does not skirt around the setter. In other words, this code:

SomeClass *ptr = [[SomeClass alloc] initWithStrAndDate:@”Foo”];

ptr.str = @”Foo 2″;

looks like a direct assignment of the string “Foo 2″ to the instance variable ‘str’. However, the work is still done through the setter. This is worth noting given that using properties and dot syntax result in a call to the setter, which is not as obvious as this [ptr setStr:@"Foo 2"] (which makes it clear the setter is involved).

by john on Jul 24, 2008. #

Comments are closed on this post. You can comment on this same post which has been moved to the iPhone Developer Tips blog: http://iphonedevelopertips.com/objective-c/properties-setters-and-dot-syntax.html

by john on Aug 16, 2008. #