2012-11-19 17 views
6

私は非常に一般的な状況を一般的な形にしていきます。私はライブラリーオブジェクトを構築していて、非同期の仕事をしてから、デリゲートメソッドを呼び出します。今、何らかの理由でARCやブロックをコールバックに使用できないと言っています。それは昔ながらのものです。このオブジェクトをWorkerと呼んでみましょう。デリゲートコールバックの間、委任者オブジェクトのライフスパンをどのように拡張する必要がありますか?

ここでは、公開アプリケーション以外にも、Workerについて何も知らないさまざまなアプリがあります。彼らは自分たちの目的のために労働者を使います。これらのクラスをコンシューマーと呼んでみましょう。

// "Private" method called internally when work is done. 
- (void)somethingFinished 
{ 
    [self.delegate workerDidFinish]; 
    [self someTask]; 
} 

そして、いくつかの特定の消費者は、このようなコールバックハンドル言う::他に何もその特定のワーカーのインスタンスを保持していない場合は、今すぐ

- (void)workerDidFinish 
{ 
    // Assume "worker" is a retain property to a Worker 
    // instance that we previously created and began working, 
    // and that it's also the sender of the message. 
    self.worker = nil; 
    // Other code... 
} 

を、我々

セイ労働者がこのようなコールバックを委任なり

困っている。作業者の割り当てが解除され、制御は -somethingFinishedメソッドに戻り、 -someTaskを再生またはガベージメモリに送信し、クラッシュする可能性があります。誰も大量のメモリ管理ルールに違反していません。

私はここで技術的な解決策を求めていません。私はいくつかのオプションを知っている。私は修正のための責任の負担が誰になるのだろうかと思っています。私はコンポーネントデザイナーとして、最初に[[self retain] autorelease]のような方法で作業者の寿命を延長するように、Workerの-somethingFinishedメソッドを実装する必要がありますか?または、コンポーネントのコンシューマがインスタンスメソッドの途中でオブジェクトを吹き飛ばしている可能性があることを認識し、後で解放するまで待つ必要がありますか?

This questionの回答はすべて、オブジェクトをコールバックから解放することが悪い考えであることを示しているようです。残念ながら、私がここで意図的に避けたデリゲートにWorker(このインスタンスのCLLocationManager)がどのくらい正確に渡されているかという質問には、多くの注意深い情報があります。 This questionは同じシナリオに悩まされており、もう1つの解決策を提示しています。

個人的には、コンシューマーがどのように責任を負うことができるかわかりません。これはメモリ管理ルールを破るものではなく、Workerのパブリックインターフェイスを丁寧に消費しています。それはもはや不要になったインスタンスをリリースするだけです。しかし、一方で、どういうわけか、途中で割り振り解除される可能性のあるオブジェクトは、人為的に自身の寿命を延長する必要があるということですか?結局のところ、デリゲートメソッドは、メッセージ送信者がメソッドの途中で割り当てを解除できる唯一の方法ではありません。

最終的には誰が修正を担当していますか?ワーカー?消費者?それは正式に決定できますか?

答えて

0

デリゲートが通知を受け取ると、workerの監視が開始され、somethingFinushedメソッドが終了したときにのみ解放されます。

+0

デリゲートはすでに委任者のオブザーバの一種です。 –

1

この例では、作業者に負担がかかると思います。私が見ている問題は、Workerオブジェクトが、その作業が終了したことをConsumerに伝えた後、内部的に何かをしているということです。従業員はコンシューマーのためだけに存在するので、コンシューマーの目的が満たされた場合、なぜコンシューマーに価値のないものをやっているのか? 「消耗品」作業が完了した後に完了する必要がある内部タスクがある場合、これらのタスクはWorkerオブジェクトのインスタンスに適切に配置されませんが、おそらく、あまり揮発性のないライブラリクラスが所有する別の内部オブジェクト消費者の行為によってdealloc'dされません。

+0

デリゲートへの呼び出しを行うオブジェクトの中には、その後の内部呼び出しを行う理由があるかもしれないと言うのは、まったくわかりません。クリーンアップルーチンと同じくらいシンプルにすることができます。これは事実ではないはずですか? –

+0

はいストレッチではありませんが、メモリ管理のシナリオを考えれば、消費者と実行ループの気まぐれで破壊されないオブジェクトにクリーンアップ/内部タスクを残す方が良いパターンかもしれません。 – foggzilla

関連する問題