1

我使用下面的代码来测试弧并帮助理解弧

NSArray __strong*  myArray = [NSArray arrayWithObjects:@"123", nil];
NSArray __weak*  yourArray = myArray;
NSArray __unsafe_unretained*  theirArray = yourArray;
myArray = nil;
NSLog(@"yourArray = %@, theirArray = %@", yourArray, theirArray);

据我了解,日志应该是:yourArray = (null), theirArray = (null) 面对日志是:yourArray = (123), theirArray = (123)

如果我更改代码并删除 __unsafe_unretained:

NSArray __strong*  myArray = [NSArray arrayWithObjects:@"123", nil];
NSArray __weak*  yourArray = myArray;
//NSArray __unsafe_unretained*  theirArray = yourArray;
myArray = nil;
NSLog(@"yourArray = %@", yourArray);

日志是正确的:yourArray = (null)

为什么如果我添加 __unsafe_unretained 局部变量来弱引用我的 NSArray 对象,它就像保留或加强我的 NSArray 对象。

任何人都可以帮助回答这个疑问。

最好的祝福

4

2 回答 2

2

在这种范围有限的简单示例中,编译器非常擅长确定对象的生命周期。它可以告诉它不应该释放数组,直到到达范围的末尾(或者至少通过这些简单的分配到达最后一次读取的末尾)。

如果您使用标记为 的 ivar,__unsafe_unretained在弱分配之后对其进行分配,并使用完全优化进行构建,您可能会看到不同的结果,即使在这种简单的情况下也是如此。此外,基本上虽然编译器可能能够处理这样的情况,其中__weak变量仍然设置并且__unsafe_unretained变量仍然能够在没有灾难的情况下读取,但关键是您不能指望它以这种方式运行。您可以指望的是,一个__weak变量在其最后一个引用消失后将被 nil'd __strong,并且编译器不会插入保留/释放指令__unsafe_unretained多变的。只要你遵守规则,你就会得到可预测的结果。一旦你不遵守规则,任何发生或不发生的事情都是不确定的......所以它可能在模拟器和 iPod 4G 上工作,但在 4S 和 5 上严重失败,而在任何 iPad 上工作一半时间。 ..关键是,结果是不确定的。

于 2012-11-21T02:50:45.330 回答
0

[NSArray arrayWithObjects:@"123", nil] 返回的对象是自动释放的,并且在自动释放池被刷新之前不会被释放。在对象被释放之前,弱引用不会被清除。unsafe_unretained 引用永远不会被 nil'd 出并且一旦对象被释放就会变得无效。

所以日志应该是

yourArray = ( 123 ), theirArray = ( 123 )

但是后来当对象被释放时,它应该是

yourArray = ( NULL ), theirArray = undefined

undefined 因为指针无效并且可能指向一个新对象或只是垃圾,它甚至可能使代码崩溃

于 2012-11-21T02:55:04.330 回答