4

考虑以下两种情况:

// 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?

4

2 回答 2

1

据我所知,当 strongOne 被释放时,对同一对象的弱引用应该更新为 nil。

这是正确的。但是当您设置strongOne为 nil 时,您并没有释放对象,您只是在更改指针。ARC 可能会调用autorelease对象strongOne指向的对象,因此直到稍后自动释放池耗尽时才会真正释放对象。

为什么这只发生在案例 2 中?

看起来 ARCrelease在这种情况下发送,所以对象被释放并且你的弱引用被立即更新。

或者,可能是编译器strongOne在将其设置为 nil 之前注意到您从未使用过,除了将其分配给弱指针,因此决定首先不分配对象。单步执行该代码,看看是否strongOne有非零值。

于 2013-08-05T21:52:47.673 回答
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.");
}
于 2013-08-05T21:57:49.443 回答