kaeruspoon

【iPhone】スレッド中で[UITableView reloadData]を使ってはいけない

76de73a1dae79a86bb99a813bd8e8e0a?s=30&d=http%3a%2f%2fkaeruspoon%.net2f2014%2fimages%2fno imageTsukasa OISHI

iPhoneアプリでスレッドを使うとき、スレッド中でUITableView reloadDataを実行するとおかしなことになります。これはスレッドセーフではないからです。
UITableViewCellで画像を外部から持ってくるときは非同期なりスレッドなりを使うと思いますが、画像取得後にUITableView reloadDataで更新しようとしてこの現象に出会いました。

リンゴの水やり

この記事にあるように、スレッド中でperformSelectorOnMainThread:withObject:waitUntilDone:modes:メソッドを使用してメインスレッド上で実行するようにしてあげれば解決できます。

ImageCache.m - 画像取得用ライブラリ

- (void) imageCache:(NSString*)url { // NSThreadでデタッチされるメソッド
    NSAutoreleasePool* pool;
    pool = [[NSAutoreleasePool alloc]init];

    NSData *data = .... // 画像データの取得処理

    if ([delegate respondsToSelector:@selector(imageCacheFinished)]) {
        [delegate performSelectorOnMainThread:@selector(imageCacheFinished) withObject:nil waitUntilDone:YES];
    }

    [pool release];
    [NSThread exit];
}

TableViewDelegate.m - TableViewのデリゲート

- (void) imageCacheFinished {
    [self.tableView reloadData];
}

こんな感じ。