ARC里面都有讲weak引用会在对象被释放后weak引用被置为nil,那什么时候被置为nil 的呢?苹果也没有明确说明,程序员没有置为nil,那么肯定是苹果做了手脚。来看看下面两个例子:
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.");
}
Outputs this:
weakOne is not nil.
weakOne is not nil.
And
// 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.");
}
Outputs this:
weakOne is nil.
我们知道的是,当strongOne被释放后,weak引用应该同样的被更新为nil.
那么case2 是为什么呢?
那么从上面的打印来看只有一种可能,那就是case1的时候,strong被释放前的if判断会给这个对象引用计数会被retain,因此weak引用只会在autoreleasepool drain的时候才会被更新为nil。
// 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.");
}