问题
In implementing an interface it seems the common method in tutorials and literature is to declare an ivar and then set the @property
then @synthesize
.
@interface MyClass : NSObject {
NSString *myString;
}
@property (nonatomic, retain) NSString *myString;
@end
However, omitting the explicit declaration and just putting @property has the same effect.
@interface MyClass: NSObject {
}
@property (nonatomic, retain) NSString *myString;
@end
So how come most people use @property
and an explicit declaration? Is it bad form not to?
回答1:
It used to be necessary. There are two different versions of the Objective-C runtime: a 32-bit-only "legacy" runtime (the old one) and a 32/64-bit runtime (the new 32-bit runtime is only used on iOS devices and for the iOS simulator).
I think the only place this is still necessary is when you're running the app in 32-bit mode (either 10.5 or 10.6). Everywhere else (64-bit Leopard, 64-bit Snow Leopard, Lion, iOS) uses the newer runtime that has "automatic ivar synthesis", and the resulting ivars are referred to as "synthesized ivars".
回答2:
Some platforms support synthesized instance variables, some don't. Explicitly declaring instance variables makes your code valid in more places, and it used to be outright necessary until very recently, so people still do it. In a few years, they probably won't anymore.
回答3:
Using modern versions of Xcode (anything about 4.2 or later) there is no reason to declare a iVar in your header, EVER. Anything publicly accessible should be declared as a property.
Many forget that Objective C objects are actually pointers to C structs. As such, any iVar that is declared in your header can be accessed directly, by passing your getters and setters, using myObject->myPublicIVar
. Especially in non-ARC code, that is extremely dangerous. The @private
directive prevents the use the ->
operator to access iVars, but still clutters the header file. There's no point in @private
when there are better ways.
Anything private should be declared within your .m file. Often, this requires a class extension, like this:
// The .h file
@interface Foo : NSObject
@property (nonatomic, strong) NSString *myPublicString;
@end
// The .m file
@interface Foo ()
@property (nonatomic, strong) NSString *myPrivateString;
@end
@implementation Foo {
NSString *myPrivateIVar;
}
// Xcode 4.5 or later will not require these @synthesize
@synthesize myPublicString = _myPublicString;
@synthesize myPrivateString = _myPrivateString;
@end
An implementation like this provides a public property backed by an iVar, a private property backed by an iVar, and a private independent iVar. I've included the @synthesize directives, but they are not necessary using modern tools.
回答4:
The @property only implements the accessor methods, the instance variable itself has to exist. Try ignoring the ivars and it will fail on runtime, if not on compile time.
来源:https://stackoverflow.com/questions/5555736/objective-c-why-do-we-declare-ivars-in-the-h-member-area-if-property-seems-to