1

非常に興味深い状況に直面しましたが、解決方法がわかりません。最初に、私のプログラムのアーキテクチャの概要を説明します。my delegate プロトコルも実装する UITableViewController 派生クラスがあります。このテーブル ビューのセルはカスタム セルであり、それぞれがデリゲート (テーブル ビュー コントローラー) に強い (割り当て) 型のプロパティを持っています。デリゲートは、いくつかの UI アクションを処理します。

クラッシュを再現するために、テーブル ビューを読み込み、そこから移動します。通常、ここではテーブルビューの割り当てが解除されますが、私の場合、セルはまだそれへの強い参照を保持しているため、メモリに残ります。問題は、この後にメモリの警告がデバイスに届くとクラッシュすることです。私は次のことが起こると推測しました:

  • テーブル ビュー コントローラがメモリ警告を受け取る
  • すべての(再利用可能な)セルを解放します
  • セルのデアロケートでは、デリゲート プロパティが nil であるため、リリースがテーブル ビュー コントローラーに送信されます。
  • 最後のセルがそのプロパティをゼロにすると、テーブル ビューの参照カウントがゼロになるため、それ自体の割り当てが解除されます。
  • セルを解放した後、テーブル ビューの didReceiveMemoryWarning のデフォルトの実装は続行されますが、既に割り当て解除されたゾンビ オブジェクト上にあります。
  • 後でゾンビに対して viewDidUnload を呼び出すと、アプリがクラッシュすることがあります。

どうすればこの状況を解決できますか?

PS: もちろん ARC は使っていません。

4

1 に答える 1

3

デリゲートを設定するときは、それを保持するのではなく、割り当てる必要があります (したがって、セルの割り当てを解除しても、テーブル ビュー コントローラーに解放メッセージを送信しないでください)。

委任オブジェクトは、委任を保持しません (保持すべきではありません)。ただし、委任オブジェクト (通常はアプリケーション) のクライアントは、委任メッセージを受信するために代理人が存在することを保証する責任があります。これを行うには、メモリ マネージ コードでデリゲートを保持する必要がある場合があります。この予防措置は、データ ソース、通知オブザーバー、およびアクション メッセージのターゲットに等しく適用されます。ガベージ コレクション環境では、リテイン サイクルの問題が適用されないため、デリゲートへの参照が強いことに注意してください。

Objective-C プログラミングの概念から

于 2012-07-05T13:40:23.377 に答える