29

私は、prepareForSegue が終了した後に viewDidLoad が呼び出されるという印象を受けました。これは Hegarty がスタンフォード大学のクラスで教えている方法です (最近では 2013 年 2 月まで)。

しかし、今日初めて、viewDidLoad が prepareForSegue が終了する前に呼び出されたことに気付きました。したがって、prepareForSegue で設定していたプロパティは、destinations viewDidLoad メソッド内の destinationViewController では使用できませんでした。

これは、予想される動作に反するようです。

アップデート

私は何が起こっているのかを理解しました。私のdestinationViewControllerには、「モデル」が更新されるたびにtableViewをリロードするカスタムセッターがありました:

DestinationViewController    
- (void)setManagedObjectsArray:(NSArray *)managedObjectsArray
    {
        _managedObjectsArray = [managedObjectsArray copy];
        [self.tableView reloadData];
    }

destinationViewController は UITableViewController のサブクラスであるため、「self.tableView」を呼び出すとビューが強制的に読み込まれます。Apple のドキュメントによると、ビュー コントローラーのビュー プロパティを呼び出すと、ビューが強制的に読み込まれる可能性があります。UITableViewController のビューは tableView です。

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html

したがって、prepareForSegue の次の行は、destinationViewController のビューを強制的にロードしていました。

vc.managedObjectsArray = <custom method that returns an array>;

この問題を解決するために、destinationViewController のモデルのカスタム セッターを次のように変更しました。

- (void)setManagedObjectsArray:(NSArray *)managedObjectsArray
    {
        _managedObjectsArray = [managedObjectsArray copy];
        if ([self isViewLoaded]) {
            [self.tableView reloadData];
        }
    }

これは、tableView が画面上にある場合にのみ、tableView をリロードします。したがって、prepareForSegue 中にビューを強制的にロードすることはありません。

このプロセスに反対する人がいる場合は、あなたの考えを共有してください。そうでなければ、これが誰かの長い眠れぬ夜を防ぐことを願っています.

4

6 に答える 6

25

私も過去に似たような混乱に陥ったことがあります。私が学んだ一般的な経験則は次のとおりです。

  1. prepareForSegue は、宛先 VC の viewDidLoad の前に呼び出されます
  2. viewDidLoad は、すべてのアウトレットがロードされた後にのみ呼び出されます
  3. ソース VC の prepareForSegue で宛先 VC のアウトレットを参照しようとしないでください。

prepareForSegue に関して学んだもう 1 つの教訓は、冗長な処理を避けることです。たとえば、既に tableView セルをストーリーボード経由で VC にセグエしている場合、tableView:didSelectRowAtIndexPath と prepareForSegue の両方を処理しようとすると、同様の競合状態に陥る可能性があります。手動セグエを利用するか、didSelectRowAtIndexPath での処理を省略することで、このような事態を回避できます。

于 2013-08-07T15:57:21.563 に答える
0

私の場合、prepareSegue で目的の presentationController のデリゲートを設定すると、viewDidLoad が呼び出されました。segue.destination.presentationController?.delegate = self を prepareSegue の最後に移動しました。

    override func prepare(for segue: UIStoryboardSegue, sender: Any?)     {
    // do stuff ....
    segue.destination.presentationController?.delegate = self
     }
于 2021-06-07T14:03:47.400 に答える
0

動的セルで同様の問題が発生し、選択時にモーダルが表示されました。prepareForSegue前に実行されましたdidSelect:atIndexPath。助けになったのは、ストーリーボードで、動的セルプロトタイプではなく、コントローラーから開始するようにセグエを再割り当てしたことです。競合状態 (?) を解決し、すべてが完全に機能しています!

于 2019-11-20T09:52:35.903 に答える