在Objective-C中,声明属性和使用@property有什么区别?

4

我知道@property在Objective-C中生成getter和setter方法。但是我看到有些类在声明属性时使用了@property,而有时只使用@property而没有属性,它们似乎都能正常工作。这两种方式有什么区别呢?


这个答案应该会有所帮助:https://dev59.com/u1HTa4cB1Zd3GeqPSpGI - Extra Savoir-Faire
2个回答

7
我知道@property在Objective-C中生成getter和setter。不,你不是这样的。@property声明了一个属性,它是一个getter并且可以选择一个setter(用于读/写属性)。getter和setter的生成由实现中的@synthesize完成(或者你编写getter和setter)。
你是指像这样声明属性的类吗?
@interface Foo : NSObject
{
    Bar* anAttribute; // <<=== this is an instance variable
}

@property (retain) Bar* anAttribute;

@end

在现代的Objective-C运行时中,如果你使用@synthesize来声明属性,你可以省略实例变量的声明,编译器会自动为你添加。无论你是否显式声明了实例变量都是个人偏好问题。
值得注意的是,在最新的编译器中,只要你没有显式地创建getter或setter方法,你就可以省略@synthesize,编译器会自动为你添加。

真的吗?哪个编译器允许您省略synthesize语句? - Moshe
@Moshe:显然是在Xcode 4.4中。http://lists.apple.com/archives/objc-language/2012/Apr/msg00037.html - JeremyP
极其有趣的解释 - RollRoll

5
在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,则它没有setter方法。
getter=,setter=控制getter和setter方法的名称。如果省略它们,则分别调用property name和set*property name*。
剩余的属性(strong、weak、retain、copy、assign)是对内存管理器的提示,它们的行为取决于是否使用ARC。如果没有使用ARC,则"retain"属性告诉setter方法自动调用retain以获取任何对象的引用。这意味着您还必须在解除分配器中调用release
"assign"属性告诉setter不要调用retain - 因此,如果对象由另一个对象释放,这个指针可能会被悬挂。
"copy"属性告诉setter调用retain并复制属性-当您获取NSDictionary时很有用,而且不希望调用者传递一个NSMutableDictionary的实例并从下面更改内容。
如果使用ARC,则通常只设置"strong"或"weak"。(强引用是retain的同义词,因此它们可以互换使用)。"strong"告诉ARC为您保留变量-"weak"告诉它不要这样做。当您有一个潜在的"保留周期",其中对象A引用对象B和对象A-如果它们都保留彼此,则会出现内存泄漏,因此您将想要使它们中的一个成为弱引用。

复制会保留吗?调用copy不足以增加保留计数吗? - samson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接