Objective-C 2.0 Properties Are Needlessly Verbose

I’ve been working in Objective-C for a little while now; not quite two years, off and on. I was really excited when Apple announced that Objective-C 2.0 was going to have generated properties, but the syntax they gave us leaves me flat, as it is needlessly verbose.

For those who don’t know, in Objective-C 1.x, if you had an instance variable in a class that you wanted to expose, you had to provide getter and setter methods for it, just like you do in Java, C++ and several other OO languages. You would see something like this in MyClass.h:

@interface MyClass : NSObject {
    NSString *name;
}

- (void) setName: (NSString *) aName;
- (NSString *) name;
@end

and then in MyClass.m, you would see this:

#import "MyClass.h"

@implementation MyClass
- (void) setName: (NSString *) aName
{
    [aName retain];
    [name release];
    name = aName;
}

- (NSString *) name
{
    return name;
}
@end

Objective-C 2.0 promised to eliminate all that boilerplate code in your *.m files for getting and setting variables. But they did it in a strange way. Now, in MyClass.h, you would see this:

@interface MyClass : NSObject {
    NSString *name;
}

@property(nonatomic, retain) NSString *name;
@end

and then in MyClass.m, this

#import "MyClass.h"

@implementation MyClass

@synthesize name

@end

Now, it certainly cut out quite a bit of code for the getter and setter, but why do I have to declare the type of the property twice? You have to declare the instance variable as usual, but then you also have to specify the data type again when you add the @property declaration. There’s no reason I can think of that those two lines couldn’t have been combined into the variable declaration. Objective-C already has tokens that are ignored, such as IBOutlet, so it shouldn’t have been an issue with breaking the parser. And the @synthesize declaration in the *.m file is annoying, but I guess it was necessary to keep the properties from being auto-created in the wrong place.  In my opinion, this is what property declarations should look like

@interface MyClass : NSObject {
    @property(nonatomic, retain) NSString *name;
}

@end

That’s it. No duplication. Simple. Elegant.

Can anyone think of a good reason why they didn’t do it like that?

12/28/2008 15:13:23 Update: As Ahruman pointed out in his comment, I misspoke about IBOutlet. It is not actually ignored, but is used to tag an instance variable for use by Interface Builder. Sorry for the confusion. And be sure to read his comment below. It’s packed with good info that I didn’t know.