强引用 / 弱引用 / 保留 / 不安全无保留引用 / 赋值引用

37

合成属性的属性: retain / assign

  • retain - 被保留,旧值被释放并被分配
  • assign - 仅被分配

所有权属性: IOS5 = strong / weak IOS4 = retain / unsafe_unretained

  • strong(iOS4 = retain)- 我是拥有者,您不能在我同意之前释放此对象 = retain

  • weak(iOS4 = unsafe_unretained)- 和assign一样,没有保留或释放操作

因此,unsafe_unretained == assign吗?

@property (nonatomic, assign) NSArray * tmp;

等于什么?

@property (nonatomic, unsafe_unretained) NSArray * tmp;

反之亦然吗?

如果是这样的话,在iOS4中应该首选哪个选项,或者为什么会有(unsafe_unretained),如果它与assign完全相同的话?

iOS4中的委托应该是unsafe_unretained还是assign?

2个回答

47
如果是在iOS4系统下,则应该使用unsafe_unretained。你需要向代码读者表明你实际上想使用弱引用,但由于所需部署的iOS版本不支持弱引用,因此只能使用unsafe_unretained
有一天你将不再支持iOS4。然后你可以搜索所有的unsafe_unretained并将它们替换为weak。这比搜索assign并确定你是否实际上想要assignweak要容易得多。
使用unsafe_unretained可以创建更具可读性和易理解的代码,使开发人员的意图更容易看到。 基本上与我们使用YES而不是1的原因相同。

在iOS4中,assign等同于unsafe_unretained,但在iOS5中,assign不等于weak,因此应该在应该是weak的地方使用unsafe_unretained?对吗? - Peter Lapisu
委托应该使用unsafe_unretained或assign? - Peter Lapisu
14
代理应该使用弱引用进行赋值。但由于iOS4上不支持weak关键字,你应该使用unsafe_unretained。我认为对于不是原始类型(如NSInteger、float等)的任何变量都没有必要使用“assign”。在手动内存管理中,我们之前使用“assign”是因为没有更好的选择。但是,“weak”会更好,因为它会在对象释放时将变量设置为nil。 - Matthias Bauch
有一些情况下,unsafe_unretained 是期望的行为。虽然并不经常出现。弱引用在对象的 dealloc 之前被置空,因此 dealloc 中对委托的事件可能需要一个 unsafe 委托。 - xtravar
2
@MatthiasBauch 一个weak代理与unsafe_unretained相比正是我所需要的!一些遗留的旧代码仍然使用unsafe_unretained,导致在执行代理方法时出现“Thread 1: EXC_BAD_ACCESS (code=1, address=0x...)”错误。代理已经被释放但没有被置空,因此它实际上通过了我的nil检查并开始执行选择器,这不是我想要的结果 :( - alexgophermix

3

在Cocoa和Cocoa Touch中有一些类还不支持弱引用,这意味着您不能声明一个弱引用属性或弱引用局部变量来跟踪它们。这些类包括NSTextView、NSFont和NSColorSpace;完整列表请参见“转换到ARC发行说明”。

如果需要使用弱引用引用其中的某个类,必须使用不安全的引用。对于属性,这意味着使用unsafe_unretained属性:

 @property (unsafe_unretained) NSObject *unsafeProperty;

对于变量,您需要使用__unsafe_unretained:

NSObject * __unsafe_unretained unsafeReference;

一个不安全的引用类似于弱引用,因为它不会保留其相关对象的生命周期,但如果目标对象被释放,它不会被设置为 nil。这意味着您将得到一个指向原始已释放对象占用的内存的悬空指针,因此称为“不安全”。向悬空指针发送消息将导致崩溃。
参考:苹果 (https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html)。

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