Using @property and @synthesize with ivar implicit creation
Ok, so lately I got this presumable bad habit of declaring my class properties with @property
create getters and setters with @synthesize
and simply use them anywhere I need them as self.name
without having a reference to the inner ivar (let @synthesize
do its work)
Now, of course this doesn't allow me to access the inner ivar (eg. name_
) but from what I've coded so far, I didn't really need it. For read-only properties I don't use @synthesize
but implement the getter myself.
Everything seems fine, but somehow I've got the feeling that this is not right because all the open source libraries I've had a look over, also declared the ivar and used it throughout the code. @property
+ @synthesize
and no ivar its definitely the lazy choice, but what are the drawbacks? Can someone give me some advice?
Also, I've read that, as a general advice, it's OK to use self.propertyName
anywhere in your class code except the dealloc
and init
methods. But as long as you make sure the object is initialize:
-(id) i开发者_StackOverflownit
{
if( (self=[super init] )) {
}
return self;
}
and you remove all key-value observers before calling [super dealloc]
everything should be fine. Right?
well the @synthesize
will create the inner ivar with the same name as the property:
@synthesize name;
- (void) dealloc {
[name release], name = nil;
[super dealloc]
}
Or give the inner ivar an other name:
@synthesize name = _name;
- (void) dealloc {
[_name release], _name = nil;
[super dealloc]
}
I use the self.name
in the init but not in the dealloc and seems to work great.
It comes down to which version of the Objective-c runtime you are building for: Modern or Legacy.
The Modern version supports "instance variable synthesis for declared properties". ie. there is no need for you to define an instance variable for each
@property
. The runtime will take care of creating one for you. By default the ivar will be named the same as the@property
. You can change the ivar name by using the format@synthesize propertyName = iVarName;
The Legacy version does not support ivar synthesis and therefore you must define an ivar for storage of your
@property
.
iPhone applications and 64-bit programs on Mac OS X v10.5 and later use the modern version of the runtime. You should assume that every other platform uses the legacy version.
What are the drawbacks? Well, the biggest one is portability - By not defining the ivars your code can run on fewer platforms e.g. it won't work on OSX 10.4. You also lose some control/flexibility & might inadvertently run into name collisions with sub- & super- classes.
It's important to remember that you should deallocate properties that you have synthesized with @synthesize
. Properties are not automatically released - you should release
any synthesized property that is not marked assign
(don't release any properties marked assign).
N.B. For extra credit you can tidy up your read-only properties. There's little reason to write your own accessor and not use @synthesize
. Simply define your property as read-only & optionally what to call the getter @property(getter=isIntReadOnlyGetter, readonly)
精彩评论