考虑以下两种情况:
// case 1
NSObject *strongOne = [[NSObject alloc] init];
NSObject * __weak weakOne = strongOne;
if (weakOne) {
NSLog(@"weakOne is not nil.");
} else {
NSLog(@"weakOne is nil.");
}
strongOne = nil;
if (weakOne) {
NSLog(@"weakOne is not nil.");
} else {
NSLog(@"weakOne is nil.");
}
输出:
weakOne is not nil.
weakOne is not nil.
和
// case 2
NSObject *strongOne = [[NSObject alloc] init];
NSObject * __weak weakOne = strongOne;
strongOne = nil;
if (weakOne) {
NSLog(@"weakOne is not nil.");
} else {
NSLog(@"weakOne is nil.");
}
输出:
weakOne is nil.
据我所知,当strongOne
被解除分配时,对同一对象的弱引用应更新为nil
。
我的问题:为什么这只发生在case 2
?
答案 0 :(得分:1)
据我所知,当strongOne被解除分配时,弱引用 同一个对象应该更新为nil。
没错。但是当你将strongOne
设置为nil时,你不会解除对象的释放,你只是在改变指针。 ARC可能会在对象autorelease
上调用strongOne
指向,因此直到稍后自动释放池耗尽时才会释放该对象。
为什么这只发生在案例2中?
在这种情况下,ARC似乎发送release
,因此对象将被释放,您的弱引用会立即更新。
或者,可能是编译器注意到在将其设置为nil之前从不使用strongOne
,除非将其分配给弱指针,因此决定不首先分配对象。逐步执行该代码,看看strongOne
是否获得非零值。
答案 1 :(得分:1)
我认为这是因为当你使用weakOne进入if语句时会增加自动释放池中的保留计数;因此,在自动释放池耗尽之前,弱指针不会为零。
// Try this
NSObject *strongOne = [[NSObject alloc] init];
NSObject * __weak weakOne = strongOne; //count 1
@autoreleasepool {
if (weakOne) {
NSLog(@"weakOne is not nil."); //count 2
} else {
NSLog(@"weakOne is nil.");
}
strongOne = nil; // count 1
if (weakOne) {
NSLog(@"weakOne is not nil.");
} else {
NSLog(@"weakOne is nil.");
}
} // count 0, therefore the weakOne become nil
if (weakOne) {
NSLog(@"weakOne is not nil.");
} else {
NSLog(@"weakOne is nil.");
}