The following doesn't complain at compilation nor runtime about no name
ivar. So why is it so common to see an ivar and @property/@synthesize
.
@interface PropTest : NSObject
{
}
@property (retain) NSString *name;
@end
@implementation PropTest
@synthesize name;
@end
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
PropTest *p = [[PropTest new] autorelease];
p.name = @"Hello, World!";
NSLog(@"%@",p.name);
[pool drain];
return 0;
}
This code prints
Hello, World!
In fact, if i access p->name
, i get a warning:
warning: instance variable 'name' is @private; this will be a hard error in the future
which indicates that an ivar is created for me if one doesn't exist.
If that's true, what's the point of creating the ivar manually (ignoring the obvious, that there are sometimes valid reasons for not using the g/setter accessor)?
Or asked differently, should i only ever create an ivar for a property when i need to bypass the accessors?
An opaque type that represents an instance variable. iOS 4.0+ iPadOS 4.0+ macOS 10.5+ tvOS 9.0+ watchOS 2.0+
A property can be backed by an instance variable, but you can also define the getter/setter to do something a bit more dynamic, e.g. you might define a lowerCase property on a string which dynamically creates the result rather than returning the value of some member variable.
@synthesize creates your setter and getter for your property (accessor methods). Without synthesize you have to write your own setter and getter implemention, like getMyString or setMyString (capitalize the first character of your property). So, the above property declaration is equivalent to: - (NSString*)myString {}
Synthesized ivars (the ability to not manually declare ivars) are a feature of the new Objective-C runtime, which still isn't being used on all systems. For 32-bit Macs (and, until recently, the iPhone simulator), you have to manually declare ivars. If you're only targeting systems with the new runtime, there's no reason to manually declare ivars.
eman's answer is correct overall, but there is one reason to still declare ivars even in the new runtime: Apple discourages synthesized accessors in init and dealloc methods. Essentially, getters and setters are allowed to have side-effects other than just setting a variable. In particular, they could trigger KVO notifications. With an ivar to talk to, you can just send release
and be done with it. But if all you have is a property, your only choice is to set it and hope you avoid any unfortunate interactions.
I'm not sure how big a problem this is in practice, to be honest. I've just superstitiously avoided it, even though I secretly doubt it would cause a problem in most cases. But Apple does make a point of this in the docs, so I assume there is some reason to be concerned.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With