33

ではviewDidUnload、iOS 6で非推奨になったので、今何をする必要がありますか?

それを削除し、そのすべてのコンテンツをに移行するdidReceiveMemoryWarningか、そのままにして、何もしませんdidReceiveMemoryWarningか?

4

5 に答える 5

68

簡単に言えば、多くの場合、何も変更する必要はありません。また、 のすべてのコンテンツを単純に に移行したくないことは間違いありません。viewDidUnloaddidReceiveMemoryWarning

一般に、私たちのほとんどはinIBOutletへの参照の設定を行い(主に Interface Builder がそこに配置するため)、メモリの一般的な解放 (たとえば、キャッシュのクリア、簡単に再作成されたモデル データの解放など) を in で行います。そのようにすれば、おそらくコードを変更する必要はありません。nilviewDidUnloaddidReceiveMemoryWarning

viewDidUnloadiOS 6 のドキュメントによると:

メモリ不足の状態でビューがパージされなくなったため、このメソッドが呼び出されることはありません。

したがって、ビューがパージされなくなったため、参照の設定をどこにも移動したくありません。それらをinなどに設定しても意味がありません。IBOutletnilnildidReceiveMemoryWarning

しかし、簡単に再作成されたモデル オブジェクトを解放したり、キャッシュを空にしたりして でメモリ不足のイベントに対応していた場合、それらviewDidUnloadは確実に に移動する必要がありdidReceiveMemoryWarningます。しかし、繰り返しになりますが、私たちのほとんどはすでにそれを持っていました。

最後に、 で何かを解放する場合は、ポップバックしたときdidReceiveMemoryWarningに再作成されることにコードが依存していないことを確認してください。viewDidLoad

applefreak が言うように、それは で何をしていたかによって異なりますviewDidUnload。質問を更新して、あなたがviewDidUnload.

于 2012-10-01T15:54:20.567 に答える
61

簡単な答え:

-didReceiveMemoryWarning は、一度も呼び出されないか、複数回呼び出される可能性があるため、バランスの取れた破棄には使用しないでください。-viewDidLoad にセットアップがある場合は、クリーンアップ コードを -dealloc に配置します。


長い答え:

状況によって大きく異なるため、一概にお答えすることはできません。ただし、次の 2 つの重要な事実があります。

1. -viewDidUnload は非推奨であり、実際には iOS6 以降では呼び出されません。したがって、そこにクリーンアップ コードがある場合、これらの OS バージョンでアプリがリークします。

2. -didReceiveMemoryWarning が複数回呼び出されるか、まったく呼び出されない可能性があります。したがって、他の場所で作成したオブジェクトをバランスよく分解するには、非常に悪い場所です。

私の答えは、プロパティを使用している一般的なケースを見ることです。次に例を示します。

@property (strong) UIView *myCustomView  // <-- this is what I'm talking about
@property (assign) id *myDelegate

ここでは、customView を作成して所有するか、InterfaceBuilder を作成して保持しているため、クリーンアップを行う必要があります。iOS 6 より前は、おそらく次のようなことをしていたでしょう:

- (void)viewDidLoad {
    self.myCustomView = [[UIView alloc] initWithFrame:…];
}
- (void)viewDidUnload {  // <-- deprecated!
    [myCustomView removeFromSuperView];
    self.myCustomView = nil;
}

...(繰り返しますが)myCustomViewは保持されたプロパティであり、あなたが作成および所有しているため、最後に注意して「解放」(nilに設定)する必要があります。

iOS 6 では、-viewDidUnloadretained プロパティを置き換えて nil に設定するのに最適な場所は、おそらく-dealloc. ともありますviewWillAppearviewDidDisappear、これらはビュー/コントローラーのライフサイクルに関連付けられているのではなく、表示サイクルに関連付けられています (一方、 -...appear メソッドは、通知リスナーの登録解除/登録に最適です!)。そのため、すべての表示の前後にビューを作成して破棄するのは適切ではない場合があります。deallocコントローラーのライフサイクルの最後に確実に呼び出される唯一のメソッドです。[super dealloc]ARC を使用している場合は、呼び出してはならないことに注意してください。

- (void)dealloc {
    self.myCustomView = nil;
}

ただし、viewDidLoadメモリ不足の状態で解放できるビュー関連のセットアップを行うために使用している場合は、メモリ不足の状況に対処する方法を示す他の投稿が完全に有効です。この場合、dealloc も使用できますが、ビューがまだ存在するかどうかを確認する必要があります。

ViewController のライフサイクル

ViewController の一般的なライフサイクルを調べることも役立つかもしれません。

これは、viewController の有効期間です(イタリック体の行は、これらのメソッドが複数回呼び出される可能性があることを意味します)

  • init: ViewController が読み込まれましたが、インターフェイス要素 (IBOutlet) はまだ利用できません (すべて nil)
  • viewDidLoad: ペン先/ストーリーボードがロードされ、すべてのオブジェクトが利用可能です。ユーザーにはまだ何も表示されません
  • viewWillAppear: ビューが表示されようとしています
  • viewDidAppear: ビューは画面上にあります
  • viewWillDisappear: ビューが消えようとしています
  • viewDidDisappear: ビューはウィンドウから取り除かれました
  • viewDidUnload: iOS6/7 では呼び出されません
  • didReceiveMemoryWarning: これが呼び出されるかどうか、いつ、どのくらいの頻度で呼び出されるかはわかりません。iOS6 より前はビューをアンロードする可能性があり、iOS6 以降はオフスクリーン キャッシュを消去するか、何もしません。
  • dealloc: viewController が破棄されようとしています

要約すると、さまざまな可能性があります。何がどこに行くのかは、何が初期化されたかによって異なります。

  • -init: または -viewDidLoad: で作成された場合は -dealloc
  • -viewWill/DidDisappear (-viewWill/DidAppear とペア)
  • -didReceiveMemoryWarning (呼び出される場合と呼び出されない場合があります)
于 2013-03-01T10:46:51.530 に答える
1

ほとんどの場合、このメソッドは古い viewDidUnload の代わりに使用できます。

// The completion handler, if provided, will be invoked after the dismissed controller's viewDidDisappear: callback is invoked.
- (void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^)(void))completion NS_AVAILABLE_IOS(5_0);

Swift 2017 の構文:

override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
    if (yourChildViewController  != nil) {
      print("good thing we did this!")
    }
    yourChildViewControllerProperty = nil
    super.dismiss(animated: flag, completion: completion)
}
于 2014-02-05T23:40:54.700 に答える
1

何をするかによって異なりますが、データを使用または解放するviewDidUnloadことができます。これを参照してください。didReceiveMemoryWarningdealloc

于 2012-10-01T14:55:18.470 に答える