0

のサブクラスのデリゲートを保持しても大丈夫ですASIHTTPRequestか?

ASIHTTPRequestと呼ばれるのサブクラスを作成しましたJSONRequest。の各インスタンスJSONRequestは独自のデリゲートであり、コールバックを処理し、コールバックをに渡しますjsonDelegate。これは、のプライベートプロパティでありJSONRequest、に応答しますrequestFinished:withResult:。ここで、結果はNSDictionaryJSON応答の表現です。これを行うために、私はオーバーロードsetDelegate:JSONRequestて実行しsuper.delegate = self; self.jsonDelegate = newDelegateました。

多くの場合、ビューコントローラであり、ユーザーが「戻る」などを押した場合にリクエストの読み込み中に割り当てが解除されることがあるjsonDelegateため、この場合は保持しても問題ありません。コールバックメソッドを呼び出した後に解放します。jsonDelegatejsonDelegateJSONRequest

これがOKであり、保持ループが発生しないことをどのように知ることができますか。

4

3 に答える 3

5

リクエストを保持しているのは何ですか?(おそらく、オペレーション キュー?誰が知っていますか?)

一般に、あなたが提案しているように見える「ファイアアンドフォーゲットアンドギブミーコールバック」メソッドは悪い考えです。要求以外に何も VC を保持していない場合、(アプリの構造が少しばかげていない限り) VC は受信したデータで何もすることができないため、続行する理由はありません。

また、間違っているように感じます: リクエストが VC を所有しているのか、それとも VC がリクエストを所有しているのか? 私は後者を期待しているので、VCもリクエストを保持する必要があります。

いくつかの例外があります:

  • CAAnimation.delegate は保持されます。おそらく、アニメーションがある時点で完了するためです (繰り返しのアニメーションの場合はどうなるかわかりません)。同じことがUIKitのアニメーションデリゲートにも当てはまるかもしれません
  • NSTimer は、おそらく NSInvocation が行うため、そのターゲットを保持します。(これを回避するために「弱いタイマー」クラスを作成しました。)
  • CADisplayLink は、おそらく NSTimer のように、そのターゲットを保持します。

これらのケースでは、ターゲットを保持しない「弱いプロキシ」クラスを使用して回避することがよくあります (そして、これを少し簡単にするために、NSTimer/CADisplayLink の周りに「弱いタイマー」ラッパーを書きました)。

あなたがすべきことは、開始したリクエストを追跡し、dealloc で次のようなことを行うことです

request.delegate = nil;
[request cancel];
self.request = nil;

同様に、適切なタイミングで通知/アクション/KVO コールバックの登録を解除する必要があります。例外があります:

  • リリース後にコールバックが送信されないことが確実な場合は、気にする必要がないため、テキスト フィールド デリゲートとボタン アクション/ターゲットをクリアする必要はありません。

例外には例外があります。

  • UIWebView (少なくとも古い OS では) は、おそらく Web スレッドに関係する何か他のものによっても保持されます。Web ビューがまだロードされている間に VC が消えると、クラッシュする可能性があります。
  • UIScrollView のスクロール コールバックも、ビューが VC の有効期間を過ぎても保持されるようにします。これをテストするには、たとえば、[Done] を押しながらフリックを開始して [Done] を放します。
于 2011-06-30T01:53:52.030 に答える
2

リリースが決定論的である場合 (エラー、タイムアウト、またはその他の予期しないイベント (接続が無期限にハングするなど) が発生した場合でも、リリースが常に発生することを約束する場合) - これで問題ありません (保持ループはありません)。 .

この場合、保持ループは必ずどこかで壊れます。

于 2011-06-30T01:35:03.483 に答える
1

この質問は元々ASIHTTPRequestに関するものであることは知っていますが、人々はこのスレッドに出くわし、ASIHTTPRequestの使用が依然としてベストプラクティスであると思わせるかもしれません。実際、開発は2011AFAIKで停止しています。

デフォルトでブロックを使用する最新のHTTPライブラリを使用すると(私はAFNetworkingを好みます)、失敗/成功ブロックで参照されるすべての変数は、ブロックが解放されるまでコピーまたは保持されます。これにより、このメモリ管理全体の問題を回避できます。ただしself、ブロックの1つで使用する場合を除き、ブロックが解放されるまで保持サイクルを作成します。

于 2012-05-04T15:29:40.540 に答える