Objective-C greift auf Eigenschaften innerhalb des Blocks zu

8

Ich habe die Blocking Programming Topics von Apple und meine Due-Diligence-Suche online gelesen, aber mir ist immer noch unklar, ob ich meine Blöcke richtig implementiere. Ich habe ein Array von Clients als eine Eigenschaft, die beim Senden einer NSNotification ausgefüllt wird. Clients werden als Tabellenansichtsdatenquelle verwendet. Der Code unten funktioniert, aber ich bin neugierig, ob es sich selbst in einen Haltezyklus setzt. Soll ich etwas wie __block id theClients = self.clients; machen und dann theClients im Block referenzieren?

@property (strong, nonatomic) NSMutableArray *clients;

%Vor%     
Hobbes the Tige 21.08.2012, 13:45
quelle

2 Antworten

8

Es gibt kein Problem beim Zugriff auf die clients-Eigenschaft, da es eine starke (d. h. beibehaltene) Eigenschaft ist. Sie brauchen also nicht das __block hier.

Ein Problem kann sein, dass self möglicherweise nicht mehr existiert, wenn die Benachrichtigung gesendet wird. Dann würden Sie auf das freigegebene Objekt zugreifen und die App kann abstürzen! Um dies zu vermeiden, sollten Sie den Beobachter in der Methode dealloc entfernen.

Die __block vor id observer ist definitiv erforderlich!

BEARBEITEN:

In iOS 5 können Sie self mit einer schwachen Referenz sicher erfassen:

%Vor%

Dann können Sie im Block sicher weakSelf.clients verwenden. Die Variable weakSelf wird automatisch in nil umgewandelt, wenn das Objekt freigegeben wird.

    
Felix 21.08.2012, 16:14
quelle
3

Ja, Sie haben einen Retain-Zyklus, zumindest bis die Benachrichtigung erfolgt. Wenn Sie auf das clients -Ivar im Block zugreifen, behält der Block self. Es wird von dem Block im Benachrichtigungszentrum beibehalten, bis die Benachrichtigung erfolgt (da Sie den Beobachter am Ende des Blocks entfernen). Wenn das in Ihrem Fall nicht erwünscht ist, können Sie einen schwachen Verweis auf self verwenden.

%Vor%

Ich sehe keinen Grund, warum Sie __block qualify observer benötigen.

Es ist auch nicht klar, dass Sie hier nichts von der Verwendung der blockbasierten API bekommen. Wenn Sie sich keine Gedanken über den möglichen Aufbewahrungszyklus machen möchten, können Sie einfach addObserver:selector:name:object: verwenden und den Text Ihres Benachrichtigungs-Callbacks in eine Instanzmethode einfügen.

    
Christopher Pickslay 22.08.2012 17:14
quelle