Reputation: 1118
Assume we have a class Foo
with a property bar
.
Declared like this in the header:
@interface Foo : NSObject {
int bar;
}
@property (nonatomic, assign) int bar;
@end
In the .m I have @synthesize bar;
of course.
Now, my question is, if I remove the int bar;
line, the property behaves the same way, so, is that line really necessary? Am I missing some fundamental concept?
Thanks!
Upvotes: 2
Views: 732
Reputation: 44856
The "modern" Objective-C runtime generates ivars automatically if they don't already exist when it encounters@synthesize
.
Advantages to skipping them:
@property
gives the type, name and use (a property!) of the ivar, so you're not losing anything.There are a few caveats:
Because of the debugger issue, at the moment I explicitly add all my ivars and flag them like this:
@interface Foo : NSObject {
#ifndef SYNTHESIZED_IVARS
int ivar;
#endif
}
@property (nonatomic, assign) int bar;
@end
My plan is to remove that block when I've confirmed the debugger is able to show the ivars. (For all I know, this has already happened.)
Upvotes: 3
Reputation: 1734
If there is not a instance variable (ivar) with the same name as the property the modern runtime creates a new ivar of the specified property name to hold the property value when it sees @synthesize.
If your property was not defined nonatomic and you want your code to be threadsafe it may help you to not reference the ivar (whether you declared it or it was synthesized), as that will prevent you from accessing it directly when the property is being changed. To my knowledge there is no way to acquire the same lock that is acquired by @synthesize for an atomic property and therefore you cannot perform safe reads of an atomic property's ivar other than by its synthesized accessor (unless you code an explicit setter and lock something yourself). If you are interested in writing you own accessors I have a blog post on that here.
I believe it is more usual to have an explicit ivar for each property, but this may be because most code is intended to be compatible with the legacy runtime rather than because it is inherently good practice.
Edit: I have corrected paragraph 1 to say that the synthesized ivar has the name of the property; I couldn't see any discussion of its name in Apple's docs so I had assumed it was not user accessible. Thanks to the commenters for pointing this out.
Upvotes: 3
Reputation: 8575
In the latest Objective-C runtime, it turns out that all ivars (in this case, bar) are dynamically added to the class from the @property/@synthesize declaration and do not need a corresponding ivar declaration in the class header. The only caveat to this is that latest Objective-C runtime which supports this feature does not include support for 32 bit applications.
This page from the excellent Cocoa with Love blog explains more.
Upvotes: 2
Reputation: 135540
If you are using the modern Obj-C runtime (e.g. with the LLVM compiler in Xcode 4), the compiler can automatically create the instance variable for you. In that case, you don't need to declare the ivar.
The modern runtime is supported by iOS, the iOS Simulator and 64-bit Mac OS X. You can't build your project for 32-bit OS X with the modern runtime.
Upvotes: 1