2

しばらくの間、解決策を回避してきた比較的単純な問題があります。ビュー コントローラーと関連する XIB があります。ビューコントローラーは と呼ばれFooterViewControllerます。 FooterViewControllerのビューは、テーブルビューのフッター ビューとして設定されます。

FooterViewControllerのビューには、ユーザーにフィードバックを表示するためのラベルが含まれています。アプリケーションによって値が変更されるまで、このラベルを保持したいと考えています。通常の状況では、そうです。ただし、メモリ警告でテストを開始したばかりで、メモリ警告に応答してビューがアンロードされた後、ラベルがクリアされることがわかりました。

この問題を解決するためにこれまでに試したことは次のとおりですFooterViewController。 の viewWillUnloadメソッドで、ラベルのテキストを というインスタンス変数に保存しますstatusString

- (void)viewWillUnload
{
    statusString = [statusLabel text];
    testInt = 5;
    NSLog(@"View will unload; status string = %@; testInt = %d", 
            statusString, testInt);

    [super viewWillUnload];
}

として宣言されている別のインスタンス変数もNSInteger testInt5 に設定していることに注意してください。

次に、FooterViewControllerviewDidLoadメソッドで、ラベルのテキストを次のように設定しようとしますstatusString

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSLog(@"Just before setting label, statusString: %@; testInt: %d", 
            statusString, testInt);
    [statusLabel setText:statusString];
    NSLog(@"View did load.");
}

ただし、これは機能しません。さらに、メモリ警告をシミュレートした後のログには、次のように表示されます。

View will unload; status string = Invalid IP address Error code: 113; testInt = 5

(「Invalid IP address Error code: 113」が statusString の正しい値であることに注意してください)

次に、FooterViewControllerもう一度移動すると、次のように表示されます。

Just before setting label, statusString: (null); testInt: 0

これは、何らかの理由で、FooterViewControllerビューが再度読み込まれたときに のインスタンス変数が再初期化されていることを示しています。最後の注意:initWithNibName:bundle:ビューをリロードする必要があるたびにメソッドが呼び出されますが、これは予想通りです。結局、ビューは NIB から再ロードする必要があります。

だから、私の質問はこれらです:

  1. ビューをアンロードおよび再ロードするプロセスで、これらのインスタンス変数が無効化またはゼロ化されているように見えるのはなぜですか?
  2. この無効化の原因となっている何か間違ったことをしている場合、それは何ですか?
  3. 私が間違ったことをしていない場合、これは通常の動作であり、ビューのロード間で状態を維持するにはどうすればよいですか?

ありがとう、ライリー

4

3 に答える 3

0

メモリ警告が発生した場合にviewDidUnloadが呼び出されることが保証されていないため、viewDidUnloadの代わりにdidRecieveMemoryWarningを使用する必要があるようです。クラッシュがアプリを完全に終了する場合は、coreDataなどを使用してデータをディスクに書き込む必要があります。ここにデータを保存してからスーパーを呼び出して、ビューが引き続き解放されるようにします。お役に立てば幸いです。

于 2012-06-18T19:33:36.397 に答える
0

何が起こっているのか、ようやくわかりました。FooterViewController問題は、親ビュー コントローラーのメソッドで割り当てと初期化のメソッドを呼び出したことviewDidLoadです。ビューがダンプされ、その後リロードされると、View Controller が再初期化されました! これにより、FooterViewController必要なインスタンス変数を保持していた元の が破棄され、新しい VC に置き換えられました。

解決策は、の親 VC の メソッドに移動[[FooterViewController alloc] init]して、初​​期化が実行サイクルごとに 1 回だけ実行されるようにすることでした。initFooterViewController

私は自分の教訓を学びました。本当にそうするつもりがない限り、View Controller を再初期化しないでください。 そのため、親ビュー コントローラーのイニシャライザーへの呼び出しを配置する場所には十分注意してください。

2人の回答者から得た助けに感謝します。

于 2012-06-19T03:01:29.437 に答える
0

statusString は、強いプロパティではなく、弱い参照のように見えます。ビューがアンロードされるとラベルの割り当てが解除されるラベルのテキストを保持することはできません。そのため、(ラベルの割り当てが解除される前に) 最初に正しい値を取得し、後で (ラベルの割り当てが解除され、弱参照が無効化された後) null を取得します。statusString を強力なプロパティに変えれば、その ARC マジックはもうあなたを悩ませません。

于 2012-06-18T18:10:27.173 に答える