Objective c 目标C:如果@property似乎自动执行,为什么我们要在.h成员区域中声明IVAR?

Objective c 目标C:如果@property似乎自动执行,为什么我们要在.h成员区域中声明IVAR?,objective-c,dynamic,properties,declaration,ivar,Objective C,Dynamic,Properties,Declaration,Ivar,在实现接口时,教程和文献中的常见方法似乎是声明ivar,然后设置@属性,然后@合成 @interface MyClass : NSObject { NSString *myString; } @property (nonatomic, retain) NSString *myString; @end 但是,省略显式声明而只放置@property具有相同的效果 @interface MyClass: NSObject { } @property (nonatomic, retain) NSS

在实现接口时,教程和文献中的常见方法似乎是声明ivar,然后设置
@属性
,然后
@合成

@interface MyClass : NSObject {
NSString *myString;
}

@property (nonatomic, retain) NSString *myString;
@end
但是,省略显式声明而只放置@property具有相同的效果

@interface MyClass: NSObject {
}

@property (nonatomic, retain) NSString *myString;
@end

那么,为什么大多数人使用
@property
和显式声明呢?不这样做不好吗?

属性只实现访问器方法,实例变量本身必须存在。尝试忽略IVAR,如果不是在编译时,它将在运行时失败。

有些平台支持合成实例变量,有些则不支持。显式声明实例变量使您的代码在更多的地方有效,而且直到最近它还一直是绝对必要的,所以人们仍然这样做。再过几年,他们可能就不会这样了。

这曾经是必要的。Objective-C运行时有两个不同的版本:仅32位的“遗留”运行时(旧版本)和32/64位运行时(新的32位运行时仅用于iOS设备和iOS模拟器)


我认为只有在32位模式(10.5或10.6)下运行应用程序时,才需要这样做。其他任何地方(64位Leopard、64位Snow Leopard、Lion、iOS)都使用具有“自动ivar合成”的较新运行时,生成的ivar被称为“合成ivar”。

使用现代版本的Xcode(任何关于4.2或更高版本的代码)永远没有理由在标头中声明ivar。任何可公开访问的内容都应声明为属性

许多人忘记了目标C对象实际上是指向C结构的指针。因此,通过使用
myObject->myPublicIVar
传递getter和setter,可以直接访问头中声明的任何iVar。特别是在非ARC代码中,这是极其危险的。
@private
指令阻止使用
->
操作符访问IVAR,但仍会使头文件混乱。当有更好的方法时,
@private
就没有意义了

任何私有内容都应该在.m文件中声明。通常,这需要一个类扩展,如下所示:

// 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

这样的实现提供了由iVar支持的公共属性、由iVar支持的私有属性和独立的私有iVar。我已经包含了@synthesis指令,但它们不是使用现代工具所必需的

-1它只会在使用传统运行时的32位平台上失败。我最近没有做太多iPhone编程。他们现在在模拟器上工作吗?我很确定他们过去不喜欢。@Chuck我想你是对的。我认为模拟器仍然使用32位遗留运行时(尽管最近可能发生了变化;我不确定)。如果我对WWDC视频的记忆正确,IIRC合成IVAR现在可以在模拟器中工作…@Wevah刚刚检查过,你是对的。模拟器大约在一年前获得了新的运行时(您对WWDC的记忆是正确的)。是的!对于您自己的应用程序和库,如果您的用户群类型正确,我建议尽可能使用最新的运行时功能。我总是对新的开源库感到恼火,这些库中充斥着这样的古语;我理解为什么(向后兼容),但它只是让我有点不高兴…:)