我认为我对 ARC 以及选择合适的生命周期限定符(__strong
、、、和)的正确用例有很好的理解。然而,在我的测试中,我发现了一个对我来说没有意义的例子。__weak
__unsafe_unretained
__autoreleasing
据我了解,两者__weak
都不__unsafe_unretained
添加保留计数。因此,如果没有其他__strong
指向该对象的指针,它会立即被释放(不可变字符串是该规则的一个例外)。在这个过程中唯一的区别是__weak
指针被设置为 nil,并且__unsafe_unretained
指针被单独留下。
如果我创建一个__weak
指向简单的自定义对象(由一个 NSString 属性组成)的指针,我会在尝试访问属性时看到预期的(空)值:
Test * __weak myTest = [[Test alloc] init];
myTest.myVal = @"Hi!";
NSLog(@"Value: %@", myTest.myVal); // Prints Value: (null)
__unsafe_unretained
同样,由于产生的悬空指针,我预计生命周期限定符会导致崩溃。然而,事实并非如此。在下一个测试中,我看到了实际值:
Test * __unsafe_unretained myTest = [[Test alloc] init];
myTest.myVal = @"Hi!";
NSLog(@"Value: %@", myTest.myVal); // Prints Value: Hi!
为什么__unsafe_unretained
对象没有被释放?
[编辑]:对象正在被释放......如果我尝试用应用程序崩溃替换第 2-3 行(并且在第一行之后立即调用NSLog(@"%@", myTest);
覆盖dealloc
的 in )。Test
我知道不可变字符串将继续可用,即使使用__unsafe_unretained
,并且直接指向 NSString 的指针也可以工作。我很惊讶我可以在一个已释放对象上设置一个属性(第 2 行),并且以后可以从指向它所属的已释放对象的指针中取消引用它(第 3 行)!如果有人能解释这一点,它肯定会回答我的问题。