2

ARC の出現により、開発者が弱参照オブジェクトを操作できるようにするために、いくつかの新しい関数が利用可能になりました。id objc_loadWeak(id *location)その一つです。この関数は、弱いオブジェクトが格納されたメモリ内の場所に対応する 1 つのパラメーターを受け取り、このオブジェクトがまだ生きている場合、またはnil割り当てが解除された場合に、このオブジェクトを返します。

オブジェクトがの場所にobjとして格納されている場合、をキーとして「弱いマップ」に配置されているようです。ただし、 を取得するには、 をキーとして使用し、 に対応する値を返すだけではありません。また、生きていない場合に戻るには、まだ生きているかどうかを確認する必要があります。weaklocationid objc_storeWeak(id *location, id obj)objlocationobjobjc_loadWeaklocationobjobjnil

ただし、objc_loadWeakオブジェクトの割り当てが解除されている可能性があるため、オブジェクトの保持カウントを読み取ることはできません。さらに、ウィーク マップ、objc_storeWeakobjc_loadWeakおよびNSObjectクラスは同じファイル ( NSObject.mm ) に実装されていますが、NSObjectdeallocメソッドは、割り当てが解除されているオブジェクトがなくなることをウィーク マップに通知しません。

weakでは、Objective-C ランタイムは、オブジェクトがまだ生きているかどうかをどのように判断するのでしょうか?

4

1 に答える 1

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);
}

ハイライトされた 3 行が魔法のようです。SideTable実装された C++ クラスNSObject.mmであり、refcntsメンバー変数はまさにそのように聞こえます: 参照カウントを保持します。

于 2013-02-13T13:44:20.853 に答える