7

誰かに片付けてもらいたい簡単な質問があります... 自分を保持するのは悪い習慣ですか?

作成したいサーバー要求オブジェクトがあります。以下のような使い方ができるようになりたいです。

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

自動解放プールが空になるとすぐにオブジェクトが自己破壊しないようにするには、init メソッドで保持を呼び出し、サーバーの応答が受信、処理され、デリゲートに配信されたら解放する必要があると思います。

しかし、このアプローチに関して、私の頭の中で何かが警鐘を鳴らしています。それを行うためのより良い方法は?

4

4 に答える 4

6

self通常のメモリ管理プロトコルに従って明確に定義された時点で解放する限り、保持に問題はありません。ある条件が満たされるまでオブジェクトが存在する必要がある場合は、存在し続ける必要がある他のオブジェクトの場合と同じように、オブジェクトがその責任を負う必要があります。

それ以外の場合は無関係なマネージャーオブジェクトを導入したり、迷信的な理由でオブジェクトの所有者に責任を負わせたりすることは、ここでの本当のアンチパターンになります。

(ガベージコレクションされたコードでの同等のアプローチは、結果が保留されている間、オブジェクトがガベージコレクションから自分自身を除外するか、そのアイデアが気に入らない場合は、ある種のコレクションを介してオブジェクトをルート化することです。)

于 2010-10-17T22:51:25.710 に答える
2

前代未聞ではありませんが、やや珍しいです。私がそれを使用した(そして自分で使用した)主な方法は、ある種の半同期オブジェクトを扱っている場合です(半同期とは、メインスレッドをブロックしないことを意味しますが、ブロックしないことも意味します)バックグラウンド スレッドで実行する; はNSURLConnectionこの法案に適合します)。たとえばNSWindowController、ウィンドウをシートとして表示し、特定のデリゲート コールバックを呼び出すためのサブクラスを作成しました。基本的に、新しいシート コントローラーをalloc/initして呼び出しbeginSheetForWindow:ます。これにより、シートが半同期的に実行され、シートが閉じられたときに適切なコールバックが呼び出されます。

呼び出し元のオブジェクトは必ずしもシートを「所有」しているとは限らないため (iOS のモーダル ビュー コントローラーの Mac バージョンと考えてください)、シート コントローラーはシート[self retain]を表示する[self release]直前、クリーンアップしてコールバックを呼び出した直後に行います。この背後にある目的は、シートが完成するまでコントローラーオブジェクトが確実に残るようにすることでした。(シート、IIRC は runloop によって保持されていましたが、コントローラーを固定する必要もありました)

私が言ったように、あなたがしたい状況に出くわすことは非常にまれですが[self retain]、それは不可能ではありません. ただし、一般的な経験則として、必要があると思われる場合は[self retain]、もう一度考えてみてください。

于 2010-10-17T15:41:42.360 に答える
1

これを行う最も簡単な方法は、リクエストの iVar を作成し、開始時にリクエストを保持し、最後のデリゲート メソッドが呼び出されたときに解放することです。

ARequestあなたが作成したクラスですか?リクエストを非同期に送信するために新しいスレッドを作成しますか?

于 2010-10-17T13:43:48.857 に答える
0

私はかつてあなたと同じことをしました。NSString に Category-Method を書き、それをサーバーに送信して印刷します。Category-Method では[self retain]、コールバック メソッドを NSString-Category-Method にできるように、 を呼び出す必要がありました。
私はそれについて非常に気分が悪く、Category-Method によってアクセスされる Singleton を使用するようにすべてを書き直しました。そのため、Singleton は必要な限り文字列を保持します。

于 2010-10-17T13:47:02.497 に答える