読者です 読者をやめる 読者になる 読者になる

UITableViewControllerのviewWillAppear:メソッドで気をつけること

かなり以前にハマったことがある内容ですが、たまたま思い出したのでメモを兼ねて書いておきます。
UITableViewControllerのサブクラスを使う場合、viewWillAppear:メソッドの中で、tableViewオブジェクトのreloadDataを呼び出すような実装を行うことが、一般的に多いと思います。
そのときに、インスタンスが生成されて最初の呼出しの時だけ、reloadが2回実行されてしまうことがあると思います。それはなぜでしょうか?
実際のコーディングでは以下の2パターンがあると思います。

パターン1
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.tableView reloadData];
}
パターン2
- (void)viewWillAppear:(BOOL)animated {
    [self.tableView reloadData];
    [super viewWillAppear:animated];
}

この現象が起こるのは、パターン1で実装した場合にだけです。
UITableViewControllerのviewWillAppear:メソッドでは、まだデータがロードされていない状態の時にだけ、reloadDataを呼び出すよう、実装されているようです。*1
パターン1では、初回はその条件に該当するので、UITableViewControllerが、reloadを呼び出してくれます。そのあとにもう1度自分でreloardDataを呼び出しているので、2回連続で呼び出されてしまいます。
回避方法は、当然ですが、パターン2で実装することですね。

UIViewControllerのリファレンスマニュアルで、viewWillAppear:メソッドの説明を読むと、このメソッドをオーバライドするときは、「どこか適切な場所でsuperを呼び出しなさい」的なことが書かれていますが、このケースでは、reloadDataメソッドを呼び出した後にsuperを呼び出すのが適切ということになると思います。

*1:この説明は、UITableViewController.hに、書かれています。