Wie kann ich __weak self in dealloc-Methode referenzieren?

8

Ich habe an verschiedenen Stellen eine Methode namens "cancelAllPendingDownloads" Dies ist eine allgemeine Methode, die verschiedene Jobs abbricht und interne Zähler aktualisiert.

Problem tritt auf, wenn es innerhalb der Dealloc-Methode

aufgerufen wird %Vor%

Nicht sicher, warum es in der Dealloc-Methode fehlschlägt, da "self" noch existiert

Wenn ich den Code in

ändere %Vor%

Der Fehler tritt in der zweiten Zeile auf

    
Avner Barr 11.11.2013, 13:30
quelle

5 Antworten

16

Nur um das "Sie sind nicht" oder "Sie können nicht" Teil der anderen guten Antworten zu machen genauer:

Die Laufzeitfunktion zum Speichern einer schwachen Referenz ist objc_storeWeak() , und die Clang / ARC-Dokumentation lautet:

  

id objc_storeWeak(id *object, id value);

     

...   Wenn value ein Nullzeiger ist oder das Objekt, auf das er zeigt, begonnen hat   Deallokation, Objekt wird null zugewiesen und nicht als __weak registriert   Objekt. Andernfalls wird das Objekt als __weak Objekt registriert oder hat sein   Registrierung aktualisiert, um auf Wert zu zeigen.

Da das Objekt self bereits mit der Aufhebung der Zuordnung begonnen hat, sollte weakSelf auf NULL festgelegt werden. (und deshalb nichts nützt).

Es scheint jedoch einen Fehler (wie hier diskutiert) zu geben ) dass objc_storeWeak() in diesem Fall abstürzt, anstatt NULL zurückzugeben.

    
Martin R 11.11.2013, 13:56
quelle
4

Wenn sich ein Objekt im Status dealloc befindet, dürfen Sie keine neuen Referenzen darauf erstellen. Betrachten Sie das Objekt als bereits zerstört. Verwenden Sie es nicht mehr in einem Callback / Delegate.

Beachten Sie, dass dlcounter niemals gelesen wird. Einfach die Verbindungen abbrechen, ohne die Ergebnisse zu lesen.

TL; DR
- Wie kann ich __weak self in dealloc Methode referenzieren?
- Verweisen Sie nicht darauf.

    
Sulthan 11.11.2013 13:43
quelle
4

Sie können eine Woche (oder einen starken) Verweis auf self in der Dealloc-Methode nicht initialisieren und anderswo verwenden - es ist zu spät, das Objekt wird unweigerlich zerstört werden.

Sie können dies jedoch versuchen:

%Vor%

Es sollte klar sein, dass es bessere Orte zum Aufrufen von Annullierungen gibt, zum Beispiel können Sie in einem View-Controller viewWillDisappear: überschreiben.

    
CouchDeveloper 11.11.2013 13:43
quelle
0

Ich gehe davon aus, dass Sie ARC für Ihr Projekt verwenden.

Direkt von Apple: Apple sprach über schwach und stark

%Vor%

Dies ist ein Artikel, der Dealloc erklärt: Dealloc-Methode erklärt und mehr

%Vor%

Nachdem Sie darauf hingewiesen wurden ... empfehle ich Ihnen dringend, Ihr Code-Design zu überarbeiten, da es keinen Grund gibt, einen schwachen Typ von (selbst) zu nennen, um Ihr Problem zu lösen Dealloc oder jede Art von Deallocing, die _ weak _typeof__self für diese Angelegenheit beinhaltet.

Was ich jedoch empfehlen kann, ist, dass die Klasse, die Sie versuchen, diese Downloads abzubrechen, die Downloads mit einer Download-UniqueID verfolgt und sie einfach bei dealloc löscht oder löscht. Es ist einfacher und einfacher zu verwalten als dieser seltsame Ruf nach dem schwachen Selbst und dem ganzen Code, den du tust.

    
Steven Hernandez 11.11.2013 14:45
quelle
0

Kurz gesagt: Sie können einen __strong Verweis auf self in dealloc anstelle von __weak für Ihre Zwecke verwenden, wenn und nur wenn diese starke Referenz das Ende von dealloc nicht überlebt. Andernfalls würde ich empfehlen, __unsafe_unretained zu verwenden, was immer noch unsicher ist, wenn es die dealloc überlebt, aber klarer zu lesen ist.

Länger: Ich hatte eine ähnliche Situation, in der das Objekt (View-Controller) während dealloc die Benachrichtigungen abbestellen sollte. Das ist ein benutzerdefiniertes Benachrichtigungssystem und das Abmelden erfordert das Erstellen eines Objekts mit einem Verweis auf die Entität, die abgemeldet wird. Ich hatte die gleiche Situation: In Dealloc gibt es keine Möglichkeit, dieses Objekt zu erstellen, weil es eine schwache Referenz benötigt, die einen Absturz verursacht hat (hier ist ein blöder Demo-Code, nicht etwas, das man in der Produktion haben würde):

%Vor%

Wenn andererseits der Hinweis stark war, scheint alles gut zu funktionieren (während Dealloc). Das Problem würde auftreten, wenn dieses neu erstellte Objekt sich selbst überleben würde:

%Vor%

Dies würde bedeuten, dass jedes Mal, wenn das dummy -Objekt aufgelöst werden müsste, versucht würde, die ref-Zählung seiner strongProperty zu verringern. Und zu diesem Zeitpunkt wurde die ViewController bereits freigegeben und freigegeben. IMHO der "sicherste" Weg, um fortzufahren, ist unsafe_unretained in diesem Fall zu verwenden. Technisch gesehen ist es das gleiche wie mit assign: Der Pointer wird unabhängig von der Speicherverwaltung zugewiesen und dieser Verweis muss nicht freigegeben werden, wenn er den Gültigkeitsbereich verlässt. Aber die Verwendung von unsafe_unretained sagt den Lesern Ihres Codes (oder der zukünftigen Sie), dass Sie sich des Risikos bewusst waren und dass es einen Grund gegeben haben muss, das zu tun, was Sie getan haben.

    
user3099609 23.04.2015 17:33
quelle