6

Im OS X v10.11 beta release notes, finde ich folgendes:Was ist ein „nicht-schwache Nullstellung Referenz“ ist

NSNotificationCenter und NSDistributedNotificationCenter nicht mehr Benachrichtigungen senden registrierte Beobachter, die freigegeben werden können. Wenn der Beobachter als eine Null-schwache Referenz gespeichert werden kann, speichert der zugrundeliegende Speicher den Beobachter als eine Nullstell-schwache Referenz. Wenn das Objekt alternativ nicht schwach gespeichert werden kann (weil es über einen benutzerdefinierten Retain-/Release-Mechanismus verfügt, der verhindert, dass die Laufzeit das Objekt schwach speichern kann), wird das Objekt als nicht schwache Nullsetzungsreferenz gespeichert . Dies bedeutet, dass Beobachter sich bei ihrer Freigabe-Methode nicht abmelden müssen. [Betonung meins]

Das ergibt für mich keinen Sinn. Wenn es eine nicht-schwache Referenz ist, wäre das dann nicht eine starke Referenz? Das NSNotificationCenter wäre also immer noch ein Eigentümer, so dass das Objekt nicht freigegeben wird (bis es manuell nicht registriert wurde), daher ist es in diesem Kontext unsinnig zu sagen, dass es "auf Null gesetzt" ist.

Wenn es sich um eine Art von __unsafe_unretained Referenz handelt, dann ist die Frage ... wie würde dann NSNotificationCenter Messaging einen Zombie vermeiden?

Antwort

4

Die Antwort dafür liegt tief in der Ziel-c-Laufzeit und wie __weak Variablen tatsächlich funktionieren. Um zu erklären, schaut sie sich ein wenig in objc_weak.mm:

id 
weak_read_no_lock(weak_table_t *weak_table, id *referrer_id) 
{ 
    ... 

    if (! referent->ISA()->hasCustomRR()) { 
     if (! referent->rootTryRetain()) { 
      return nil; 
     } 
    } 
    else { 
     BOOL (*tryRetain)(objc_object *, SEL) = (BOOL(*)(objc_object *, SEL)) 
      object_getMethodImplementation((id)referent, 
              SEL_retainWeakReference); 
     if ((IMP)tryRetain == _objc_msgForward) { 
      return nil; 
     } 
     if (! (*tryRetain)(referent, SEL_retainWeakReference)) { 
      return nil; 
     } 
    } 

    return (id)referent; 
} 

Wie Sie sehen können, wenn benutzerdefinierte -retain und -release Methoden, die von einem Objekt verwendet werden, es ist nicht garantiert, dass sie schwachen Verweis auf alle unterstützen (beachten Sie auch, dass Sie kann ein völlig anderes Objekt für die schwachen Referenzen eines Objekts verwenden, obwohl das ein Thema für eine andere Zeit ist).

Dies ist, weil schwache Referenzen von objc_destructInstance bereinigt werden, die objc_clearDeallocating ruft, die weak_clear_no_lock ruft.

Jetzt muss objc_destructInstance nicht von benutzerdefinierten Objektimplementierungen aufgerufen werden, obwohl die meisten Objekte es aufrufen.

Somit ist die Laufzeit können Sie die Methode -allowsWeakReference (und retainWeakReference) implementieren schwache Verweise auf das Objekt zu deaktivieren, in welchem ​​Fall es höchstwahrscheinlich durch Umstellen -dealloc auf dem Objekt zero'd aus. Natürlich sind dies alles Implementierungsdetails, so dass NSNotificationCenter seine eigene innovative Art und Weise haben kann, Dinge zu tun, aber das ist meine beste Vermutung, ohne zu versuchen, NSNotificationCenter zu disassemblieren.

+0

Für eine beispielhafte Implementierung der Art von Swizzling Ich beziehe mich auf, werfen Sie einen Blick auf [MAZeroingWeakRef] (https://github.com/mikeash/MAZeroingWeakRef/). –

+0

Eine ausführliche Antwort und genau die Art von Erklärung, die ich mir erhofft hatte. Vielen Dank! – natevw

0

Die Deklaration einer Eigenschaft als stark macht diese Eigenschaft zu einer starken Referenz. Wenn Sie es als schwach deklarieren, wird eine schwache Nullreferenz verwendet.Die unsafe_unretained Modifikator verwendet einen Nicht-Nullstellung schwacher Verweis

Kurz: non-weak zeroing reference == unsafe_unretained refernce

Referenz:

https://mikeash.com/pyblog/friday-qa-2011-09-30-automatic-reference-counting.html http://www.jessesquires.com/UIKit-changes-in-iOS-9/

+0

Diese Frage ist anders als der häufigere Fall. Nicht "was ist eine nicht-Nullstellung schwache Referenz". Die Frage ist hier: "Was ist eine nicht-schwache Nullstellungsreferenz". – natevw

+0

Sie meinen, sie sind der Unterschied? – Proton