This question already has answers here:
Why isn’t my weak reference cleared right after the strong ones are gone?

(4个答案)


7年前关闭。




请考虑以下两种情况:
// 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中发生?

最佳答案

我认为这是因为当您使用带有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.");
}

07-27 13:31