Übergeben Sie immer schwache Referenz von Selbst in Block in ARC?
Ich bin ein wenig verwirrt darüber, block-Verwendung in Objective-C. derzeit benutze ich einen BOGEN, und ich habe ganz viele Blöcke in meiner app, die derzeit jeweils bezogen auf self
anstatt seine schwache Referenz. Kann das sein, dass die Ursache für diese Blöcke behalten self
und halten es davon ab, dealloced ? Die Frage ist, soll ich immer ein weak
Referenz self
in einem block ?
-(void)handleNewerData:(NSArray *)arr
{
ProcessOperation *operation =
[[ProcessOperation alloc] initWithDataToProcess:arr
completion:^(NSMutableArray *rows) {
dispatch_async(dispatch_get_main_queue(), ^{
[self updateFeed:arr rows:rows];
});
}];
[dataProcessQueue addOperation:operation];
}
ProcessOperation.h
@interface ProcessOperation : NSOperation
{
NSMutableArray *dataArr;
NSMutableArray *rowHeightsArr;
void (^callback)(NSMutableArray *rows);
}
ProcessOperation.m
-(id)initWithDataToProcess:(NSArray *)data completion:(void (^)(NSMutableArray *rows))cb{
if(self =[super init]){
dataArr = [NSMutableArray arrayWithArray:data];
rowHeightsArr = [NSMutableArray new];
callback = cb;
}
return self;
}
- (void)main {
@autoreleasepool {
...
callback(rowHeightsArr);
}
}
InformationsquelleAutor der Frage the_critic | 2013-11-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hilft es, sich nicht auf den
strong
oderweak
Teil der Diskussion. Konzentrieren Sie sich stattdessen auf die Zyklus Teil.Einen behalten Zyklus ist eine Schleife, die passiert, wenn Objekt A Objekt behält B, und Objekt B Objekt behält A. In dieser situation, wenn entweder Objekt freigegeben wird:
So, diese beiden Objekte, wird nur hängen, um im Speicher für die Lebensdauer des Programms, obwohl Sie sollten, wenn alles richtig funktioniert, werden aufgehoben.
So, was wir sind besorgt über behalten Zyklenund es gibt nichts über Blöcke in und von sich erstellen, diese Zyklen. Dies ist nicht ein problem, zum Beispiel:
Den block behält
self
aberself
nicht behalten blockieren. Wenn der ein oder andere wird freigegeben, kein Zyklus ist erstellt und wird alles aufgehoben, wie es sollte.Wo Sie in Schwierigkeiten geraten, ist so etwas wie:
Nun, Ihr Objekt (
self
) eine explizitestrong
Verweis auf den block. Und der block hat eine implizite starken Bezug zurself
. Das ist ein Zyklus, und jetzt weder Objekt wird freigegeben, richtig.Da, in einer situation wie dieser
self
per definition bereits einestrong
Verweis auf den block, es ist in der Regel am einfachsten zu beheben, indem eine explizit schwachen Verweis aufself
für den block zu verwenden:Dies sollte aber nicht die Standard-Muster, die Sie Folgenbeim Umgang mit Bausteinen, die nennen
self
! Dies sollte nur verwendet werden, um zu brechen, was sonst eine retain-Zyklus zwischen dem selbst und dem block. Wenn Sie waren zu erlassen, dieses Muster überall, würden Sie Gefahr laufen, vorbei an einem block an etwas hat ausgeführt, nachself
wurde aufgehoben.InformationsquelleAutor der Antwort jemmons
Sie nicht haben, um immer eine schwache Referenz. Wenn Ihr block ist nicht erhalten, wird aber ausgeführt und dann gelöscht, können Sie erfassen selbst stark, als es nicht erstellen Sie einen Zyklus behalten. In einigen Fällen, Sie wollen sogar den block zu halten, die selbst bis zum Abschluss des Blocks, damit es nicht vorzeitig freigeben. Wenn, jedoch, Sie erfassen den block stark, und innen erfassen, selbst, wird es schaffen eine retain-Zyklus.
InformationsquelleAutor der Antwort Leo Natan
Ich bin völlig einverstanden mit @jemmons.
"Dies sollte aber nicht die Standard-Muster, die Sie Folgen beim Umgang mit Bausteinen, die nennen sich selbst! Dies sollte nur verwendet werden, um zu brechen, was sonst eine retain-Zyklus zwischen dem selbst und dem block. Wenn Sie waren zu erlassen, dieses Muster überall, würden Sie Gefahr laufen, vorbei an einem block an etwas hat ausgeführt, nachdem selbst wurde aufgehoben."
Herüber zu kommen dieses problem kann man definieren, einen starken Hinweis über die weakSelf in den block.
InformationsquelleAutor der Antwort Ilker Baltaci
Als Leo anmerkt, den code, den Sie Hinzugefügt, um Ihre Frage würde nicht vorschlagen, eine starke Referenz-Zyklus (ein.k.ein., retain-Zyklus). Eine betriebsbedingte Problem, dass könnte die Ursache für eine starke Referenz-Zyklus würde sein, wenn die Bedienung nicht immer veröffentlicht. Während Ihr code-snippet deutet darauf hin, dass Sie nicht definiert haben Ihren Betrieb werden gleichzeitig, aber wenn Sie haben, wäre es nicht veröffentlicht, wenn Sie nie veröffentlicht
isFinished
oder wenn Sie zirkuläre Abhängigkeiten, oder so ähnlich. Und wenn der Betrieb nicht freigegeben ist, wird die view-controller würde nicht freigegeben werden. Ich würde vorschlagen, hinzufügen von einem Haltepunkt oderNSLog
in Ihrem Betriebdealloc
Methode und bestätigen, dass Sie immer genannt.Sagte Sie:
Retain-Zyklus (starke Referenz-Zyklus) - Probleme, die auftreten, mit die Blöcke werden wie die retain-Zyklus-Probleme, die Sie vertraut sind mit. Ein block wird halten starke Referenzen auf alle Objekte innerhalb des Blocks, und es wird nicht lassen Sie diese starke Referenzen, bis der block selbst ist freigegeben. Also, wenn block-Referenzen
self
oder auch nur mit Verweis auf eine Instanz-variable vonself
das wird halten starken Bezug auf sich selbst, das ist nicht gelöst, bis der block freigegeben wird (oder in diesem Fall, bis derNSOperation
Unterklasse veröffentlicht.Weitere Informationen finden Sie in der Vermeiden Sie Starke Referenz Zyklen bei der Aufnahme selbst Abschnitt der Programmierung mit Objective-C: Arbeiten mit Blöcken Dokument.
Wenn Ihr view-controller ist immer noch nicht veröffentlicht, Sie müssen einfach zu identifizieren, wo die ungelösten starken Verweis befindet (vorausgesetzt, Sie bestätigt die
NSOperation
ist immer freigegeben). Ein typisches Beispiel ist die Verwendung einer sich wiederholendenNSTimer
. Oder einige benutzerdefiniertedelegate
oder andere Objekt, das fälschlicherweise die Aufrechterhaltung einerstrong
Referenz. Häufig können Sie die Instrumente auf die Spur, wo Objekte sind, die immer Ihre starke Referenzen, z.B.:Oder in Xcode 5:
InformationsquelleAutor der Antwort Rob
Einige Erklärungen ignorieren, ein Zustand, der von der retain-Zyklus [Wenn eine Gruppe von Objekten verbunden ist, durch einen Kreis von starken Beziehungen, Sie halten sich gegenseitig am Leben, auch wenn es keine starken Referenzen, die von außerhalb der Gruppe.] Für mehr Informationen, Lesen Sie die Dokument
InformationsquelleAutor der Antwort x4snowman
Dies ist, wie Sie verwenden können, die selbst in den block:
//Aufruf von der block
InformationsquelleAutor der Antwort Ranjeet Singh