Wie kann ich diese Warnung in xcode vermeiden? Hier ist das Code-Snippet:
[player(AVPlayer object) addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(0.1, 100)
queue:nil usingBlock:^(CMTime time) {
current+=1;
if(current==60)
{
min+=(current/60);
current = 0;
}
[timerDisp(UILabel) setText:[NSString stringWithFormat:@"%02d:%02d",min,current]];///warning occurs in this line
}];
objective-c
cocoa-touch
automatic-ref-counting
avplayer
retain
user1845209
quelle
quelle
timerDisp
eine Eigenschaft in der Klasse?player(AVPlayer object)
undtimerDisp(UILabel)
?Antworten:
Die Erfassung von
self
hier erfolgt mit Ihrem impliziten Eigenschaftszugriff vonself.timerDisp
- Sie können nicht aufself
oder Eigenschaftenself
innerhalb eines Blocks verweisen, der von stark beibehalten wirdself
.Sie können dies umgehen, indem Sie einen schwachen Verweis auf erstellen,
self
bevor Sie auftimerDisp
Ihren Block zugreifen :quelle
__unsafe_unretained
stattdessen.self
, sondern von der Hauptversandwarteschlange beibehalten. Liege ich falsch?Und eine sehr wichtige Sache, die Sie beachten sollten: Verwenden Sie Instanzvariablen nicht direkt im Block, sondern als Eigenschaften eines schwachen Objekts. Beispiel:
und vergessen Sie nicht zu tun:
Ein weiteres Problem kann auftreten, wenn Sie eine schwache Kopie eines Objekts übergeben, das von niemandem aufbewahrt wird:
Wenn
vcToGo
die Zuordnung aufgehoben und dann dieser Block ausgelöst wird, werden Sie wahrscheinlich mit einem nicht erkannten Selektor in einen Papierkorb stürzenvcToGo_
, der jetzt eine Variable enthält . Versuchen Sie es zu kontrollieren.quelle
Bessere Version
Das Ganze wäre also so:
Ich habe diesen Artikel oft gelesen. Dies ist ein ausgezeichneter Artikel von Erica Sadun über das Vermeiden von Problemen bei der Verwendung von Blöcken und NSNotificationCenter
Schnelles Update:
Zum Beispiel wäre in kurzer Zeit eine einfache Methode mit Erfolgsblock:
Wenn wir diese Methode aufrufen und
self
im Erfolgsblock verwenden müssen. Wir werden die[weak self]
undguard let
Funktionen verwenden.Dieser sogenannte stark-schwache Tanz wird von beliebten Open-Source-Projekten verwendet
Alamofire
.Weitere Informationen finden Sie im Swift-Style-Guide
quelle
typeof(self) strongSelf = self;
außerhalb des Blocks (anstelle von __schwach) getan haben, dann in dem BlockstrongSelf = nil;
nach der Verwendung gesagt ? Ich verstehe nicht, wie Ihr Beispiel sicherstellt, dass schwaches Selbst zum Zeitpunkt der Ausführung des Blocks nicht gleich Null ist.In einer anderen Antwort sagte Tim:
Das ist nicht ganz richtig. Es ist in Ordnung, dies zu tun, solange Sie den Zyklus irgendwann unterbrechen. Nehmen wir zum Beispiel an, Sie haben einen Timer, der ausgelöst wird und einen Block hat, der sich selbst behält, und Sie behalten auch einen starken Bezug zum Timer in sich. Dies ist vollkommen in Ordnung, wenn Sie immer wissen, dass Sie den Timer irgendwann zerstören und den Zyklus unterbrechen werden.
In meinem Fall hatte ich gerade diese Warnung für Code, der Folgendes tat:
Jetzt weiß ich zufällig, dass clang diese Warnung nur dann ausgibt, wenn festgestellt wird, dass die Methode mit „set“ beginnt (und einem weiteren Sonderfall, den ich hier nicht erwähne). Ich weiß, dass keine Gefahr besteht, dass es eine Retain-Schleife gibt. Deshalb habe ich den Methodennamen in „useY:“ geändert. Das ist natürlich möglicherweise nicht in allen Fällen angemessen, und normalerweise möchten Sie eine schwache Referenz verwenden, aber Ich fand es wert, meine Lösung zur Kenntnis zu nehmen, falls sie anderen hilft.
quelle
Oft ist dies kein Aufbewahrungszyklus .
Wenn Sie wissen, dass dies nicht der Fall ist, müssen Sie keine fruchtlosen Schwachen in die Welt bringen.
Apple zwingt uns diese Warnungen sogar mit der API auf ihre
UIPageViewController
, die eine festgelegte Methode (die diese Warnungen auslöst - wie an anderer Stelle erwähnt - mit dem Gedanken, dass Sie einen Wert auf einen ivar setzen, der ein Block ist) und einen Vervollständigungs-Handler-Block (in dem) enthalten Sie werden sich zweifellos auf sich selbst beziehen).Hier sind einige Compiler-Anweisungen, um die Warnung aus dieser einen Codezeile zu entfernen:
quelle
Hinzufügen von zwei Cent zur Verbesserung von Präzision und Stil. In den meisten Fällen verwenden Sie
self
in diesem Block nur ein oder mehrere Mitglieder von , wahrscheinlich nur, um einen Schieberegler zu aktualisieren. Castingself
ist übertrieben. Stattdessen ist es besser, explizit zu sein und nur die Objekte zu werfen , die Sie wirklich benötigen, innerhalb des Blocks. Zum Beispiel, wenn es eine Instanz istUISlider*
, sagen wir,_timeSlider
tun gerade folgendes vor dem Block Erklärung:Dann einfach
slider
innerhalb des Blocks verwenden. Technisch gesehen ist dies genauer, da der potenzielle Aufbewahrungszyklus nur auf das Objekt beschränkt wird, das Sie benötigen, nicht auf alle Objekte im Innerenself
.Vollständiges Beispiel:
Darüber hinaus ist das Objekt, das in einen schwachen Zeiger umgewandelt wird, höchstwahrscheinlich bereits ein schwacher Zeiger im Inneren,
self
wodurch die Wahrscheinlichkeit eines Aufbewahrungszyklus minimiert oder vollständig beseitigt wird. Im obigen Beispiel_timeSlider
ist tatsächlich eine Eigenschaft als schwache Referenz gespeichert, z.In Bezug auf den Codierungsstil werden Variablendeklarationen wie bei C und C ++ besser von rechts nach links gelesen. Die Erklärung
SomeType* __weak variable
in dieser Reihenfolge lautet natürlicher von rechts nach links als :variable is a weak pointer to SomeType
.quelle
Ich bin kürzlich auf diese Warnung gestoßen und wollte sie etwas besser verstehen. Nach einigem Ausprobieren stellte ich fest, dass eine Methode entweder mit "Hinzufügen" oder "Speichern" beginnt. Ziel C behandelt Methodennamen, die mit "neu", "zuordnen" usw. beginnen, als Rückgabe eines beibehaltenen Objekts, erwähnt jedoch nichts (was ich finden kann) über "Hinzufügen" oder "Speichern". Wenn ich jedoch einen Methodennamen auf diese Weise verwende:
Ich werde die Warnung in der Zeile [selbst erledigt] sehen. Dies wird jedoch nicht:
Ich werde fortfahren und die Methode "__weak __typeof (self) schwachSelf = self" verwenden, um auf mein Objekt zu verweisen, aber ich mag es wirklich nicht, dies zu tun, da dies ein zukünftiges Ich und / oder einen anderen Entwickler verwirren wird. Natürlich könnte ich auch nicht "add" (oder "save") verwenden, aber das ist schlimmer, da es die Bedeutung der Methode wegnimmt.
quelle