4

考慮以下兩種情況:弱引用何時在Objective-C中更新爲零?

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

您還應該使用Release-build而不是Debug對其進行測試。結果可能不同...... –

回答

1

我認爲這是因爲當你進入if語句與weakOne會增加保留計數在autorelease池;因此,在自動釋放池耗盡之前,弱指針不會爲零。

// 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."); 
} 
1

據我知道,當strongOne被釋放,弱引用 同一個對象應更新到零。

沒錯。但是當您將strongOne設置爲零時,您不會取消分配對象,您只需更改指針。 ARC可能會調用autorelease指向的對象strongOne指向,因此該對象實際上不會被釋放,直到自動釋放池耗盡時爲止。

爲什麼只有在情況2中才會發生?

看起來ARC在這種情況下發送release,因此該對象被釋放並且您的弱引用被立即更新。

或者,編譯器可能會注意到,在將其設置爲nil之前,從不使用strongOne,除非將其分配給弱指針,因此決定不首先分配對象。查看代碼,看看strongOne是否有非零值。