2012-11-06 10 views
10

Was ist die richtige Methode zum Hinzufügen von Objekten in NSMutableArray, die stark durch die Eigenschaft definiert ist.Was ist der richtige Weg zur Vermeidung von Retain Cycle während der Verwendung von Blöcken

[tapBlockView setTapBlock:^(UIImage* image) { 
    [self.myImageArray addObject:image]; // self retain cycle 
} 

Wenn ich schwach Referenz etwas wie

__weak NSMutableArray *array = self.myImageArray; 
[tapBlockView setTapBlock:^(UIImage* image) { 
    [array addObject:image]; // If I will do this then how will I update original Array ? 
} 

erstellen Ich habe auch versucht

__weak id weakSelf = self; 
[tapBlockView setTapBlock:^(UIImage* image) { 
    [weakSelf storeImageInaNewMethod:image]; // Calling SToreImageInaNewMethod 
} 

und

-(void)storeImageInaNewMethod:(UIImage*)image { 
    [self.myImageArray addObject:image]; // This again retaining cycle 
} 

Was ist der richtige Weg, ursprüngliche Objekt zu aktualisieren definiert durch Eigenschaft?

+0

Blöcke gleicher Funktion sind pointers.Can't Sie einfach den Block auf Null gesetzt, wenn Sie dies nicht tun Brauchst du es nicht mehr? –

Antwort

8

Versuchen Sie eine Kombination der 2. und 3..

__weak id weakSelf = self; 
[tapBlockView setTapBlock:^(UIImage* image) { 
    [weakSelf.myImageArray addObject:image]; 
} 
+0

Beachten Sie, dass dies nur gültig ist, wenn Sie weakSelf in der ersten Zeile des Blocks verwenden, wenn Sie zuerst etwas anderes machen, dann benötigen Sie Kaans Antwort. – malhal

0

Ihre zweite und dritte erscheinen korrekt. Die zweite funktioniert, weil Sie keine Kopie des Arrays erstellt haben, so dass immer noch auf das Original verwiesen wird. Der dritte funktioniert, weil der Bezug auf das Selbst schwach ist.

+0

Der zweite funktioniert nur, wenn 'self.myImageArray' einen direkten Verweis auf den ivar zurückgibt. Das ist möglicherweise keine sichere Annahme. – rmaddy

+0

Stimmt, das ist ein guter Punkt –

12

Nach Antwort des maddy - das ist ab 2012 WWDC Vortrag über GCD und asynchrone Programmierung:

__weak MyClass *weakSelf = self; 

[tapBlockView setTapBlock:^(UIImage* image) { 
    __strong MyClass *strongSelf = weakSelf; 
    if(strongSelf) { 
     [strongSelf.myImageArray addObject:image]; 
    } 
}]; 
+0

Ich verstehe nicht warum du dich wieder in __strong verwandelst? Ich denke nur dieser Code ist ausreichend? [weakSelf.myImageArray addObject: Bild]; – Tariq

+6

Der Grund für die Umwandlung in '__strong' besteht darin, zu garantieren, dass, wenn' weakSelf' noch am Leben ist, wenn die erste Zeile des Blocks ausgeführt wird, sie für den Rest der Ausführung des Blocks weiterlebt. –

+0

Wenn Sie Warnungen aktiviert haben, dann würden Sie sehen, warum der __strong benötigt wird: Eine schwache Variable kann zu jedem Zeitpunkt verschwinden, auch in der Mitte des Aufrufs weakSelf.myImageArray, was sicherlich Probleme verursachen wird. – gnasher729

1

In Ihrem Fall müssen Sie nur ein Array verweisen, die von self Bezug genommen wird, so:

Funktioniert einwandfrei bereitgestellt, dass self.myImageArray nicht verschiedene Array-Referenzen bei verschiedenen zurückgibt ent zeiten. Es gibt keinen Zyklus: Das aktuelle Objekt verweist auf das Array und den Block, und der Block verweist wiederum auf das Array.

Wenn self.myImageArray verschiedene Array Referenzen zurückkehrt wie verschiedenen Zeiten dann einen schwachen Verweis auf self verwenden, Ihren Fall 3.

Verwandte Themen