2

隨着ARC的出現,一些新的功能可供開發人員使用弱引用的對象。 id objc_loadWeak(id *location)就是其中之一。這個函數接收一個參數,對應於存儲弱對象的內存中的一個位置,如果它仍然存在則返回該對象,或者如果它被釋放,則返回nilObjective-C運行時如何知道弱引用的對象是否還活着?

看來,當一個對象objid objc_storeWeak(id *location, id obj)存儲爲weak在一個位置locationobj被放在一個「弱圖」,以location作爲重點。但是,爲了檢索objobjc_loadWeak不僅可以使用location作爲關鍵字並返回對應於obj的值。它還必須檢查obj是否還活着,如果它不在,則返回nil

但是,objc_loadWeak無法嘗試讀取該對象的保留計數,因爲該對象可能已被釋放。此外,儘管在相同的文件(NSObject.mm)中執行弱映射objc_storeWeak,objc_loadWeakNSObject類,但是NSObjectdealloc方法不向弱映射發信號通知正被釋放的對象正在消失。

那麼,Objective-C運行庫如何確定一個weak對象是否仍然存在?

回答

9

NSObject的dealloc方法不會向弱映射表明正在釋放的對象正在消失。

它的確如此。

- [NSObject dealloc] 

調用

_objc_rootDealloc(self); 

這反過來又調用

object_dispose() 

進而調用

objc_destructInstance() 

這最後調用

objc_clear_deallocating() 

這最後一個功能是這樣的:

void 
objc_clear_deallocating(id obj) 
{ 
    assert(obj); 
    assert(!UseGC); 

    SideTable *table = SideTable::tableForPointer(obj); /* *** THIS LINE *** */ 

    // clear any weak table items 
    // clear extra retain count and deallocating bit 
    // (fixme warn or abort if extra retain count == 0 ?) 
    OSSpinLockLock(&table->slock); 
    if (seen_weak_refs) { 
    arr_clear_deallocating(&table->weak_table, obj); /* *** THIS LINE *** */ 
    } 
    table->refcnts.erase(DISGUISE(obj)); /* *** THIS LINE *** */ 
    OSSpinLockUnlock(&table->slock); 
} 

三個突出線條做的魔力。 SideTable是一個C++類,在NSObject.mm中實現,其中refcnts成員變量完全按照它聽起來的樣子進行:它保存引用計數。

+0

哦,是的。直到最後,我沒有遵循鏈條。當我到達'object_dispose()'時停止。由於這個函數被放置在另一個文件中,我認爲它與弱引用處理無關。非常感謝你! – LuisABOL 2013-02-13 13:53:19

+0

@ LuisAntonioBotelhoO.Leite不客氣。 – 2013-02-13 13:54:01

相關問題