Objective C: Why do we declare ivars in the .h member area if @property seems to do it automatically?

夙愿已清 提交于 2019-12-18 04:01:30

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!