我知道@property 在Objective-c 中生成getter 和setter。但是我见过一些类,它们使用各自的@property 声明属性,有时只是没有属性的@property,并且接缝以相同的方式工作。有什么不同?
2 回答
我知道@property 在Objective-c 中生成getter 和setter。
不,你没有。 @property
声明一个属性,它是一个 getter 和可选的 setter(用于读/写属性)。getter 和 setter 的生成是由@synthesize
实现中的(或由您编写 getter 和 setter)完成的。
但我见过一些类,它们用各自的@property 声明属性
你的意思是这样吗?
@interface Foo : NSObject
{
Bar* anAttribute; // <<=== this is an instance variable
}
@property (retain) Bar* anAttribute;
@end
在现代 Objective-C 运行时,如果你@synthesize
是属性,你可以省略实例变量声明,编译器会为你放入。是否显式声明实例变量是个人喜好问题。
只是为了让您有点困惑,在最新的编译器中,您可以省略@synthesize
并且只要您没有显式创建 getter 或 setter,编译器就会为您放入它。
在 ios 5.0 下,您可以将十种不同的属性附加到属性声明:nonatomic、readwrite、readonly、getter= name、setter= name、strong、retain、copy、weak、assign。(强,弱是 ios 5.0 下的新功能,只有在使用 ARC 时才有意义)。
nonatomic 声明不应保护变量访问免受多线程并发访问。这不是默认设置,尽管 99% 的时间都是您想要的(因为如果您不进行多线程处理,这种保护会使您的代码运行速度变慢而没有任何好处)。
readwrite/readonly 应该相当明显 - readwrite 是默认设置,如果您声明一个属性 readonly,它没有设置器。
getter=, setter= 控制应该调用什么 getter 和 setter 方法。如果省略它们,它们将分别称为属性名称和 set*property name*。
其余属性(强、弱、保留、复制、分配)是内存管理器的提示,它们的行为取决于您是否使用 ARC。如果你不是,那么“retain”属性会告诉 setter 方法在它获得引用的任何对象上自动调用retain 。这意味着您还必须在释放器中调用release。
“assign”属性告诉setter不要调用retain——所以如果对象被另一个对象释放,这个指针可能会悬空。
“复制”属性告诉设置器调用保留并制作属性的副本 - 当您获得 NSDictionary 并且您不希望调用者传递 NSMutableDictionary 的实例并更改内容时,这很有用从你下面出来。
如果您使用 ARC,通常只会设置“强”或“弱”。(强是保留的同义词,因此它们可以互换使用)。“强”告诉 ARC 为您保留变量 - “弱”告诉它不要。当您有潜在的“保留周期”时,“弱”很有用,其中对象 A 引用对象 B 和对象 A - 如果它们都相互保留,则存在内存泄漏,因此您需要将其中一个设为弱参考。