7

2つのUITableViewControllerがあり、ストーリーボードを使用してそれらの間をセグエしています。

ではprepareForSegue:sender:、最初のVCがWebサービスからNSArrayを取得し、ダウンロードされたデータを使用して宛先VCのモデルを設定します。ダウンロード部分をに入れて、dispatch_queue_t非同期で実行され、UIスレッドをブロックしないようにします。テーブルセルをタップし、UIActivityIndi​​catorViewの回転を開始して写真をダウンロードし、写真がダウンロードされたら、スピナーを停止してセグエを続行します。

最初のUITableViewControllerには、次のprepareForSegue:sender:メソッドがあります。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"SelectPlace"]) {
        NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];

        UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc]
                                            initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
        [spinner startAnimating];
        self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:spinner];

        __block NSArray *photos = [[NSMutableArray alloc] init];
        dispatch_queue_t downloadQueue = dispatch_queue_create("flickr download", NULL);
        dispatch_async(downloadQueue, ^{
            photos = [FlickrFetcher photosInPlace:[self.places objectAtIndex:indexPath.row] maxResults:50];
        });
        dispatch_release(downloadQueue);
        [spinner stopAnimating];
        [segue.destinationViewController setPhotos:photos withTitle:[[sender textLabel] text]];
    }

}

現在、スピナーを表示したり、ダウンロードが完了するのを待たずに、すぐにセグエを実行しています。

メインスレッドをブロックせずに、またすぐにセグエせずに、データを非同期にダウンロードして宛先ビューを準備するにはどうすればよいですか?

4

2 に答える 2

9

デスティネーションViewControllerにデータをロードしてもらいます。ユーザーがテーブル内の行を選択したら、すぐに新しいViewControllerにセグエする必要があります。これは、ユーザーインターフェイスをスッキリさせるために必要です。でprepareForSegue、デスティネーションビューコントローラに、ロード自体を実行するために必要なデータを提供します。次にviewWillAppear、宛先View Controllerで、データを非同期でロードします。

デスティネーションビューコントローラを汎用的に保ち、デスティネーションビューコントローラからのフリッカーフォトフェッチを回避したい場合は、などのメソッドを持ち、デスティネーションビューコントローラにに設定されているポインタを持つプロトコルを設定getThePhotoDataできdataSourceます。次に、宛先View Controllerで、非同期で呼び出します。フリッカー写真のフェッチは、セグエをトリガーしたビューコントローラーに実装されるメソッドで行われます。selfprepareForSegueviewWillAppear[dataSource getThePhotoData]getThePhotoData

于 2012-10-21T18:37:04.517 に答える
5

prepareForSegueでは、セグエを停止することはできません。すべてのデータが揃うまで、セグエをトリガーしないでください。したがって、手動のセグエを作成し、すべてのデータがダウンロードされたらそれを呼び出すことをお勧めします。

たとえば、イベントのチェーンは次のようになります。

  1. viewDidLoadの通知(dataReady :)のVCレジスタで、deallocで登録を解除します。
  2. ユーザーがダウンロードボタンをクリックしてターゲットメソッドを起動すると、スピナーアニメーションが開始されます
  3. ターゲットメソッドは、いくつかのブロック(できればいくつかのモデル)を含むすべてのデータをダウンロードします。
  4. ブロックの最後に通知を送信します([[NSNotificationCenter defaultCenter] postNotificationName ...)、
  5. VC dataReady:が呼び出され、スピナーを停止して[self PerformSegueWithIdentifier:...]を呼び出します
  6. セグエがトリガーされます
于 2012-10-21T18:27:48.850 に答える