@property and @synthesize in objective-c
While I was playing and figure out how things work in https://github.com/enormego/EGOTableViewPullRefresh I found mysterious of @property and @synthesize. Here is the code I mentioned
EGORefreshTableHeaderView.h
@interface EGORefreshTableHeaderView : UIView {
id _delegate;
EGOPullRefreshState _state;
UILabel *_lastUpdatedLabel;
UILabel *_statusLabel;
CALayer *_arrowImage;
UIActivityIndicatorView *_activityView;
}
@property(nonatomic,assign) id <EGORefreshTableHeaderDelegate> delegate;
EGORefreshTableHeaderView.m
@synthesize delegate=_delegate;
I have read this http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html and from what I understand is it create new name for _delegate which is delegate. (Am I right with this understanding ?)
But I still doesn't understand why they have to make thing complicated with thos开发者_如何学编程e @synthesize = directive.
How complicated is it, really? It's just a bit of syntax that lets you specify the ivar that you want to use to back the property for which you're telling the compiler to create accessors. If they didn't provide this or something equivalent, then you'd always have to have your property names match your ivar names, and there are reasons that you might not want that.
If you don't need to name your ivars differently, then you don't have to bother with specifying the ivar name. In fact, you don't have to create ivars at all for your properties... if you don't, the compiler will create them for you.
Update: As of the middle of 2013, LLVM defaults to synthesizing accessors for properties, so in most cases you no longer need to specify @synthesize
at all. The one case where you would still use it is when you want to back the property with a different instance variable than the one that the compiler would generate for you. Also, the default name for the ivar that backs a property will be the property name prefixed with an underscore. So, the code in the OP's example could be simplified by deleting the lines:
id _delegate;
and:
@synthesize delegate=_delegate;
I've removed my previous advice against using an underscore prefix since it clearly disagreed with the current fashion and default behavior of the compiler. As far as I know, it's still poor form to use an underscore prefix for your method names, however.
Also, it has come to my attention that at least one person interpreted the first line of my response, "How complicated is it, really?" as condescending. I hope that was only one person's impression -- I definitely didn't intend any condescension, but was only trying to frame my response around the OP's assertion that the @synthesize xxx=_xxx;
directive makes things complicated. There's a lot to absorb when you're starting out; hopefully the new "synthesize by default" behavior will reduce the burden for newcomers.
You are right, using
@synthesize foobar=_foobar;
is a bit pointless in most cases , but at an abstract level it does allow you to return the value of some other variable entirely. As in ...
@synthesize foobar=fluffybunny;
Lets you get or set the value of fluffybunny
each time you use the accessor .foobar
However in terms of the@synthesize
complexity , would you rather write
-(void)setFoobar:(id)aobject {
[self willSetValueForKey:"foobar"];
id old = foobar;
foobar = [aobject retain];
[old release];
[self didSetValueForKey:"foobar"];
}
-(id)foobar {
[self willAccessValueForKey:"foobar"];
id obj = [self primitiveValueForKey:@"foobar"];
[self didAccessValueForKey:"foobar"];
return obj;
}
Or
@synthesize foobar;
Thats not particularly well written as ive forgotten how to do them well but the @synthesize directive stops you having to write accessors so many times. It one one of the things that sucked heavily about Obj-C 1.0.
Free code , dont knock it.
精彩评论