关于assign、retain、copy和strong的澄清?

8

我还是Objective-C的新手,在设置属性时,对于assign、retain、copy、strong等属性应该如何使用仍有些困惑。

例如,我已经声明了以下类型 - 我应该如何设置这些属性?

@property (nonatomic, ??) NSMutableArray *myArray
@property (nonatomic, ??) NSString *myString
@property (nonatomic, ??) UIColor *myColor
@property (nonatomic, ??) int *myIn
@property (nonatomic, ??) BOOL *myBOOL

Thanks....

2个回答

20

需要再次强调的是,这取决于上下文。在非 ARC(自动引用计数)情况下:

@property (nonatomic, copy) NSMutableArray *myArray
@property (nonatomic, copy) NSString *myString
@property (nonatomic, retain) UIColor *myColor
//Note the change to an int rather than a pointer to an int
@property (nonatomic, assign) int myInt
//Note the change to an int rather than a pointer to an int
@property (nonatomic, assign) BOOL myBOOL

在我的Array上的拷贝是为了防止另一个"owner"修改你设置的对象。在ARC项目中,情况会有所改变:

@property (nonatomic, copy) NSMutableArray *myArray
@property (nonatomic, copy) NSString *myString
@property (nonatomic, strong) UIColor *myColor
//Note the change to an int rather than a pointer to an int
@property (nonatomic, assign) int myInt
//Note the change to an int rather than a pointer to an int
@property (nonatomic, assign) BOOL myBOOL

在您的情况下,变化主要是针对 myColor 属性。由于您不直接管理引用计数,因此不需要使用 retain。而 strong 关键字是一种声明对该属性“拥有权”的方式,类似于 retain。还提供了另一个关键字 weak,通常用于对象类型而非赋值。苹果公司常见的 weak 属性示例是委托(delegate)。我建议您除了查看 Memory Management Guide,还应多次阅读 Transitioning to ARC Release Notes,因为其中包含的细微差别远不止可以在 SO 帖子中轻易解释清楚。


谢谢David。只是想指出,使用“strong”不仅仅是“类似于”“retain”,它是一个直接的同义词(我相信你已经知道了,只是想为其他读者解释一下)。http://developer.apple.com/library/mac/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html#//apple_ref/doc/uid/TP40011226-CH1-SW4 - dooleyo

0
@property (nonatomic, copy) NSMutableArray *myArray
@property (nonatomic, copy) NSString *myString
@property (nonatomic, retain) UIColor *myColor
@property (nonatomic) int myIn
@property (nonatomic) BOOL myBOOL

复制可变对象,或具有可变子类的对象,例如NSString:这可以防止它们被其他所有者修改。虽然我认为苹果不建议将可变对象用作属性。

其他对象通常会被保留,但例外是委托,它们被分配以防止所有权循环。

intBOOL这样的基本类型被分配,这是@property的默认选项,因此不需要指定,但如果您觉得它有助于可读性,也可以添加它。


2
为什么在苹果公司不推荐将可变对象用作属性?(我应该澄清这些是在单例中) - wayneh
我认为这是一种安全考虑,比如你将一个NSMutableString传递给一个保留它的对象。那么这个对象现在可以修改你的数据(如果它们是你的类,那么这可能是你想要的,但如果不是,使用不可变类型更加安全)。这更像是一种建议而不是硬性规定。 - wattson12
1
@wattson 声明可变对象为复制属性的整个目的是为了避免另一个所有者修改它们。只要你复制它们(这是苹果的建议),就没有理由不将它们用作属性。 - UIAdam
@UIAdam 你说得对,复制它们是安全的。但我在想,如果你有一个可变属性,那么一个引用到你的类的对象可能会改变数据,这可能是设计时考虑的因素,但对我来说似乎不是很好的封装。 - wattson12
当然,另一个类仍然可以访问您复制的对象并对其进行更改。如果您想确保安全,可以始终声明自己的getter方法,该方法也返回对象的副本。 - UIAdam
显示剩余2条评论

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