2014-02-20 5 views
5

Kann doFirst hier einen Rückhaltezyklus verursachen?Ruft das Aufrufen einer Methode innerhalb eines Blocks, die eine andere Methode aufruft, die sich auf self bezieht, einen Retain-Zyklus auf?

@interface Example : NSObject 
@property (nonatomic, strong) void (^block)(); 
@end 

@implementation Example 

- (void)doFirst 
{ 
    __weak id weakSelf = self; 
    self.block =^{    
     [weakSelf doSecond]; 
    }; 

    self.block(); 
} 

- (void)doSecond 
{ 
    self.value = //... 
    // do other stuff involving self 
} 
@end 
+0

Ein nützlicher Tipp, wenn man sich auf eine weakSelf bezieht, ist etwas wie folgt: '__ weak typeof (self) weakself = self'. Macht die Dinge einfacher, wenn Code an verschiedenen Orten wiederverwendet wird usw. – liamnichols

Antwort

5

Im Gegensatz zu Blöcken sind Methoden keine Objekte; Sie können keinen permanenten Bezug auf Objekte haben.

Ihr Code würde keinen Retain-Zyklus verursachen. Die Tatsache, dass der Code innerhalb von doSecond auf self verweist, bedeutet explizit nicht, dass self eine zusätzliche Zeit erhalten bleiben würde. Wenn Ihr Block doSecond aufruft, kommt sein self von der weakSelf Referenz in doFirst.

Hinweis: Wenn Sie Blöcke als Eigenschaften speichern, use (nonatomic, copy) anstelle von (nonatomic, strong).

+0

Warum würde 'copy' vs' strong' hier eine Rolle spielen? Es wird von der Klasse Example erstellt und gehört nicht von einer anderen Klasse. AFAIK, würde das nicht einfach zusätzlichen Aufwand beim Erstellen des Blocks hinzufügen? –

+0

Unabhängig von 'copy' vs' strong' Semantik ist dies eine klare Antwort und macht sehr viel Sinn, vor allem in Bezug auf 'Methoden sind keine Objekte'. +1. Vielen Dank. –

+1

@ JRG-Developer Sie benötigen eine Kopie für Blöcke, die auf dem Stack erstellt wurden. In dem Code, den Sie anzeigen, spielt es keine Rolle, denn Sie rufen den Block vor dem Verlassen der Methode auf, in der er definiert ist. Wenn Sie jedoch möchten, dass der Block beibehalten wird, müssen Sie eine Kopie davon erstellen, bevor die Methode beendet wird. – dasblinkenlight

0

Nein Es wird nicht. Weil es nur auf eine Methode zeigt, die nicht innerhalb von Methoden hält, die nur eine Referenz als gleiches Objekt haben.