2010-10-17 7 views
7

Ich habe eine einfache Frage, die ich gerne von jemandem geklärt hätte ... Ist es eine schlechte Übung, sich selbst zu behalten?Schlechte Praxis, um 'sich selbst' zu behalten?

Ich habe ein Server-Anfrage-Objekt, das ich gerne machen würde. Ich möchte in der Lage sein, es in der folgenden Art und Weise zu nutzen:

ARequest *request = [ARequest request: someParam]; 
request.delegate = self; 
[request begin]; 

Um für das Objekt selbst nicht so schnell wie der Autofreigabepool Destruct abgelassen wird, ich denke, ich brauche einen behalten Aufruf es ist init-Methode und dann eine Freigabe, sobald die Server-Antwort empfangen, verarbeitet und an ihren Delegaten übergeben wurde.

Aber etwas ist eine Warnung Glocke in meinem Kopf mit diesem Ansatz. Bessere Möglichkeiten, es zu tun?

Antwort

6

Es ist nichts falsch daran, self beizubehalten, solange Sie es an einem genau definierten Punkt gemäß dem normalen Speicherverwaltungsprotokoll freigeben. Wenn ein Objekt selbst existieren muss, bis eine Bedingung erfüllt ist, sollte es die Verantwortung dafür übernehmen, genauso wie es für jedes andere Objekt erforderlich ist, um fortzufahren.

Die Einführung von ansonsten überflüssigen Managerobjekten oder das Hinausschieben der Verantwortung aus obskuren Gründen auf den Objektbesitzer wäre hier das wahre Antimuster.

(Der äquivalente Ansatz in Garbage Collection Code wäre für das Objekt selbst von der Garbage Collection auszuschließen, während Ergebnisse anhängig sind, oder Wurzel es durch eine Sammlung von einer Art, wenn Sie diese Idee nicht mögen.)

1

Der einfachste Weg, dies zu tun wäre, eine iVar für Ihre Anfrage zu erstellen, die Anfrage beim Start zu behalten und sie zu veröffentlichen, wenn die letzte Delegate-Methode aufgerufen wird.

Ist ARequest eine von Ihnen erstellte Klasse? Erstellt es einen neuen Thread, um die Anfrage asynchron zu übermitteln?

+0

Ja, ARequest ist im Grunde genommen eine Klasse, die eine NSURLConnection erstellt, um eine Anfrage asynchron zu senden. Ich könnte ein ivar verwenden, aber ich könnte einige Anfragen gleichzeitig senden, so dass ich dann eine Sammlung von Anfragen in irgendeiner Form verwalten müsste. Apple scheint ein Muster zu verwenden, das keine Pflege dieser Art erfordert (zum Beispiel SKProductsRequest). – Tricky

0

Ich habe einmal dasselbe gemacht wie du. Ich habe eine Category-Methode auf NSString geschrieben, um es an einen Server zu senden, der es ausdrucken wird. In der Category-Methode musste ich [self retain] aufrufen, damit die Callback-Methoden eine NSString-Category-Methode sein können.
Ich habe mich so schlecht gefühlt, dass ich alles umgeschrieben habe, um ein Singleton zu verwenden, auf das mit der Category-Methode zugegriffen wird. Daher behält der Singleton die Zeichenfolge so lange wie nötig bei.

+0

Ja, das ist die Sache ... Es fühlt sich aus irgendeinem Grund "schlecht" an, aber ich frage mich, ob es wirklich ist? Apple verwaltet dies zum Beispiel in SKProductsRequest, aber ist es über ein [self remain] oder pflegen sie irgendwo eine Sammlung ausstehender Anfragen? – Tricky

2

Es ist nicht unüblich, aber es ist etwas ungewöhnlich. Der Hauptweg, den ich gesehen habe (und es selbst benutzt habe), ist, wenn Sie mit einer Art halbsynchronem Objekt zu tun haben (halbsynchron bedeutet das, dass es den Haupt-Thread nicht blockiert, aber auch nicht Ausführen auf einem Hintergrundthread; ein NSURLConnection würde diese Rechnung passen). Zum Beispiel schrieb ich eine Unterklasse von NSWindowController, die speziell zum Anzeigen eines Fensters als Blatt und zum Aufrufen einiger bestimmter Delegatenrückrufe gedacht war. Grundsätzlich würden Sie alloc/init einen neuen Blatt-Controller und beginSheetForWindow: aufrufen. Dies würde das Blatt halb synchron ausführen und dann einen geeigneten Rückruf aufrufen, wenn das Blatt geschlossen wurde.

Da das aufrufende Objekt nicht unbedingt „eigenen“ das Blatt (man denke an es als Mac-Version eines modalen View-Controller auf iOS), das Blatt Controller tut [self retain] unmittelbar vor dem Blatt zeigt, und [self release] unmittelbar nach der Reinigung Callbacks aufrufen und aufrufen. Der Zweck dahinter war sicherzustellen, dass das Controller Objekt bleiben würde, bis das Blatt fertig war. (Das Blatt, IIRC, wurde von der Runloop beibehalten, aber ich brauchte auch den Controller zu bleiben)

Wie gesagt, es ist sehr selten, eine Situation zu finden, wo Sie [self retain] wollen, aber es ist nicht unmöglich. Als allgemeine Faustregel gilt jedoch, dass Sie, wenn Sie denken, dass Sie [self retain] benötigen, erneut darüber nachdenken sollten.