initWithNibname:
、awakeFromNib
、loadView
、viewDidLoad
、viewDidAppear:
、layoutSubviews
、Iなど、オーバーライドする多くのメソッドがあります。これらのメソッドを呼び出す順序を決定することはできません。
そのうちの1つを「ハート」でオーバーライドします。
詳細な説明はありますか?
CocoaビューとviewController管理 で、舞台裏で多くのことが行われています。
1。 viewControllerオブジェクト
最も基本的には、viewControllerは汎用コントローラーオブジェクトです。初期化されて初めて割り当てられたとき、それに関連付けられたビューオブジェクトはありません。ビューは、必要な場合(および必要な場合)にのみインスタンス化されます。したがって、ビューを考慮しない場合、viewControllerのライフサイクルは他のオブジェクトと同じです。
UIViewController * myVC = [[UIViewController alloc] initWith...];
...
[myVC release];
ViewControllersに指定された初期化子は -initWithNibname:bundle:
です。 nibを指定すると、viewControllerはそのnibからビューを自動的にロードし、定義したIBOutletを接続できます(詳細については以下を参照)。
2。ビューのロードとアンロード
ViewControllerは、必要に応じてビューをロードします。これは通常、-view
メソッドが初めて呼び出されたときに発生し、UIの初期化方法に応じて、プログラム内でいつでも発生する可能性があります。ビューは、UIの管理方法に応じて、プログラムの有効期間中に何度か破棄され、再ロードされる場合があります。 viewControllerがビューが必要であるがまだロードされていないことを識別した場合、-loadView
メソッドが呼び出されます。基本的なメッセージフローは次のようになります。
view
loadView
viewDidLoad
-view
メソッドをオーバーライドすると、-loadView
およびviewDidLoad
は自動的に呼び出されないことに注意してください。 -loadView
をオーバーライドする場合、must viewControllerのview
プロパティを設定します。それ以外の場合、-view
への次の呼び出しは、ロードプロセスを再度トリガーします。
ビューは、view
プロパティをnil
に設定するだけで、プログラムの有効期間中いつでもアンロードできます。ビューにスーパービューがない限り(つまり、現在アクティブビュー階層の一部ではない場合)、-didReceiveMemoryWarning
のデフォルト実装はこれを自動的に行います。メッセージフローは次のとおりです。
view = nil
viewDidUnload
2a。プログラムでビューをロードする
-loadView
をオーバーライドすることを選択した場合、ビュー、サブビュー、他のviewController、およびこれらのオブジェクト間の接続を任意の方法で作成できます。もちろん、これは、作成するオブジェクトに関するメモリ管理も担当することを意味します。サブクラスが-loadView
をオーバーライドする場合、nil
とnibName
の両方に対してbundle
を使用して初期化する必要があります。
2b。ペン先からビューをロードする
Nibファイルを使用する場合、-loadView
のデフォルト実装は自動的にそのnibファイルを開き、オブジェクトをインスタンス化し、それらの間に接続を追加し、メモリ管理を処理します。
Nibファイルでは、裏で多くのことが行われるため、事態は少し複雑になります。 -awakeFromNib
メソッドは、すべてのオブジェクトに対して呼び出されます。これは、nibファイルがロードされるときにインスタンス化され、nibファイル内の他のオブジェクトが完全にロードされる保証はありません。と呼ばれます。
3。ビューの表示
-viewWillAppear:
、-viewDidAppear:
、-viewWillDisappear:
、および-viewDidDisappear:
は、特に、あるビューから別のビューへのアニメーション化されたトランジション中に、ビューが画面上に表示または非表示されている場合にのみ呼び出されます。これらのメソッドは、プログラムの存続期間中に何度も呼び出される可能性があります。これは、ビューがナビゲーションスキームでスワップインおよびスワップアウトされるためです。
4。ビューレイアウト
-layoutSubviews
メソッドはnotUIViewController
の一部です。 UIView
オブジェクトの境界が変更されたときに呼び出されます。プログラムでカスタムUIView
サブクラスを使用する場合、Cocoaのデフォルトの自動サイズ変更メソッドに依存する代わりに、このメソッドを使用してカスタムサブビューレイアウトを実行できます。
5。すべてをまとめる
複雑なため、このプロセスを実行するにはさまざまな方法がありますが、通常のタイムラインは次のようになります。
-[viewController initWithNibname:Bundle:]
-[viewController awakeFromNib]
-[viewController loadView]
-[view awakeFromNib]
-[viewController viewDidLoad]
-[viewController viewWillAppear]
-[viewController viewDidAppear]
...
-[viewController viewWillDisappear] // user navigated away
-[viewController viewDidDisappear]
...
-[viewController viewWillAppear] // user navigated back
-[viewController viewDidAppear]
...
-[viewController viewWillDisappear] // user navigated away
-[viewController viewDidDisappear]
...
-[viewController setView:nil] // memory warning, perhaps
-[viewController viewDidUnload]
...
-[viewController loadView] // user navigated back
-[view awakeFromNib]
-[viewController viewDidLoad]
-[viewController viewWillAppear]
-[viewController viewDidAppear]
...
私は最近これを再訪し、テストプロジェクトを作成しました: https://github.com/Janek2004/ViewControllerTest
IOSシミュレーターでプロジェクトを実行して、UIViewControllerサブクラスメソッドの実行順序を確認します。ストーリーボードの代わりにNibファイルを使用するか、View Controllerをプログラムで読み込むと、順序が異なる場合があります。
-[ViewController viewDidAppear:]ビューがビュー階層に追加されたことをView Controllerに通知します。このメソッドをオーバーライドして、ビューの表示に関連する追加のタスクを実行できます。
-[ViewController viewWillDisappear:]ビューがビュー階層から削除されようとしていることをView Controllerに通知します。このメソッドはビューに応答して呼び出されますビュー階層から削除されます。このメソッドは、ビューが実際に削除される前、およびアニメーションが設定される前に呼び出されます。ビューがビュー階層に追加されたことをView Controllerに通知します。このメソッドをオーバーライドして、ビューの表示に関連する追加のタスクを実行できます。
プロセスのもう1つの重要な瞬間は、subviewでlayoutSubviewsが呼び出されることです。ストーリーボードで設定された制約が適用されたのはこの時点であり、すぐではありません。制約された座標に基づいて、ビューのサブビューを調整する必要がある場合は、layoutSubviewsで調整する必要があります。 viewDidLayoutSubviewsでそれを行うと、それらのサブビューにはまだ制約が適用されていないため(文書ごとに「各サブビューは独自のレイアウトの調整を担当するため」)、viewDidAppearで行う場合、サブビューが座標を変更するのをユーザーが見るため、明らかに遅すぎます。したがって、プロセスのもう1つの重要なステップは次のとおりです。
-viewController viewWillAppear
-viewController viewWillLayoutSubviews
-viewController viewDidLayoutSubviews
---> viewController.[any subview] layoutSubviews
-viewController viewDidAppear
from Apple UIViewControllerドキュメント:
UIViewControllerの新しいサブクラスを定義するときは、コントローラーによって管理されるビューを指定する必要があります。これらのビューを指定するには、2つの相互排他的な方法があります。手動またはnibファイルを使用する方法です。ビューを手動で指定する場合、loadViewメソッドを実装し、それを使用してルートビューオブジェクトをビュープロパティに割り当てる必要があります。 nibファイルを使用してビューを指定する場合、loadViewをオーバーライドする必要はありませんが、代わりにInterface Builderでnibファイルを作成してから、initWithNibName:bundle:メソッドを使用してView Controllerオブジェクトを初期化する必要があります。 nibファイルを使用したビューの作成は、Interface Builderアプリケーションを使用してビューをグラフィカルに(プログラムではなく)作成および構成できるため、多くの場合より簡単です。ただし、両方の手法の最終結果は同じです。つまり、適切なビューのセットを作成し、それらをビュープロパティを通じて公開します。
私の頭の上から:
layoutSubviewsが入る手掛かりなし
私は通常、アプリ起動デリゲートを含むこれらすべてのデリゲートにNSLog(またはブレークポイント)を配置し、デバッガーの順序に従うことでこの問題を解決します。
-これは表示のみに関連しています: -viewWillAppear: -viewDidAppear: -viewWillDisappear:および -viewDidDisappear: は、ビューが表示されているときにのみ呼び出されます。 -viewController viewDidLoad -viewController viewWillAppear -viewController viewDidAppear 他のメソッド -viewController viewDidDisappear -viewController viewWillDisappear -viewController viewDidUnload
E.Jamesの優れた説明に感謝します。投稿にまだコメントすることはできませんが、簡単な視覚的説明については、View Controllerプログラミングガイドの このフローチャート を参照してください。そして、これはトピック外ですが、 アプリ起動シーケンスのグラフ については、iOS Application Programming Guideを参照してください。