2017-03-14 13 views
0

tableView.reloadData()を呼び出すと、別のスレッドでリロードが開始されたようです。すぐにデータ構造に追加したセルを選択しようとすると、まだTableViewで再読み込みされていない可能性があります。 TableViewがreloadData()プロセスを完了したことを通知する方法はありますか?私の実際のコードは:UITableViewのリロードが完了したときの通知方法

DispatchQueue.main.async { 
     self.tableView.reloadData() 
     self.selectNode(node: newNode) 
    } 

です。selectNodeは、そのノードを表示しているTableViewCellを見つける関数です。 TableViewはまだそれを再表示していないので、失敗することがよくあります。 TableViewがリロード後にすべての行を要求したかどうかを確認する待機ループを挿入することで解決策を「ブルートフォース」することができますが、より洗練されたソリューションが得られることを期待していました。私はまた、一般的に待機ループに不快です。

+0

reloadData()は、私がベストプラクティスと信じているメインスレッド、つまりDispatchQueue.main.async {self.tableView.reloadData()} 'で実行したいかもしれません。それはあなたが走っている競争状態を避けるのに役立ちます。 –

+0

reloadData()はバックグラウンドスレッドでは機能しません(メインスレッドで呼び出していると仮定します)。呼び出しが返されるとすぐに実行されます。あなたがする必要があることは他にありません。たぶんあなたの問題は、表示されている行だけがリロードされるということでしょうか? [参考文献](https://developer.apple.com/reference/uikit/uitableview/1614862-reloaddata)を参照してください。 – zpasternack

+0

私のコードからわかるように、私はメインスレッドでそれを呼び出していて、その後メインスレッドでセルを選択しようとしています。自分で行選択を管理しています。 reloadDataを呼び出すのは、テーブルの下部に新しい項目を追加しただけで、その項目を選択したいからです。呼び出し直後にセルがまだ再ロードされていないため、selectメソッドが失敗します。経験的には、reloadDataがメインスレッド上で実行されていないように見えます。 tableViewのprintステートメントcellForRowAt:reloadData呼び出しから返された後も正常に続行されているように見える – user493245

答えて

0

私はこの問題に気付いた解決策と、tableView.reloadDataがどのように機能するかについて何を示唆しているのかを知りたいと思いました。

func addNewItem() { 
    // here we create the kind of item the user chose 

    //ending with this 
    tableView.reloadData() 
    queueCheckForDone() 
} 

func queueCheckForDone() { 
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .milliseconds(1), execute: { 
     self.checkForDone() 
    }) 
} 

func checkForDone() { 
    if items[items.count-1].viewCell != nil {  // has last view cell been created 
     self.selectItem(item: addedItem) 
    } else { 
     queueCheckForDone() 
    } 
} 

問題はすぐにreloadData後、私は私がちょうど追加されたセルを選択することを望んだということでした。まず、ここで働く私は最終的に到着したコードです。しかし、tableViewの読み込みが完了していないため、呼び出し直後は表示されませんでした。 reloadDataはメインスレッド上で実行したいが、私のコードはイベントハンドラでメインスレッド上でブロックしていた。私が待つスレッドを放棄するとすぐに、ミリ秒でreloadDataはスレッドを捕捉し、テーブル全体をリロードしました(> 250ms)。私が最終的にコントロールを再開したとき、私が探していたセルは常にそこにあったので、checkForDoneテストのelse節は決して実行しませんでした。

関連する問題