1

prepareForSegue コールバックに 3 つの NSInvocationOperation を持つ NSOperationQueue があり、すべての非同期タスクが終了した後に別のビュー コントローラーに移動する必要があります。すべての非同期タスクの完了について、この別の画面に移動した後にのみ通知を受け取るにはどうすればよいですか?

私は成功せずにこれを試しました:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

});

編集:

私は何かを理解していないようです:

-(void)initPurchase{

    [operationQueue cancelAllOperations];

    NSInvocationOperation *downloadImageOperation = [[NSInvocationOperation alloc] initWithTarget:[BSImageDownloader getInstance] selector:@selector(downloadImageSync:) object:@"http://.........jpg"];


    NSInvocationOperation *createImageOperation = [[NSInvocationOperation alloc] initWithTarget:[BSImageCreator getInstance] selector:@selector(createImage:) object:@"dsadsadsa"];


    NSInvocationOperation *saveImageOperation = [[NSInvocationOperation alloc] initWithTarget:[BSImageSaver getInstance] selector:@selector(saveImageAsPng:) object:[BSSharedObject getInstance].createdImage];

    [createImageOperation addDependency:downloadImageOperation];
    [saveImageOperation addDependency:createImageOperation];


    [operationQueue addOperation:downloadImageOperation];
    [operationQueue addOperation:createImageOperation];
    [operationQueue addOperation:saveImageOperation];


}


-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{

    [[BSPopupManager getInstance]showWaitingPopup];


    dispatch_group_t group = dispatch_group_create();

    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), 
                         ^{
                             Purchase *purchase = [[Purchase alloc] init];
                             [purchase initPurchase];
                         });

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        [[BSPopupManager getInstance] closeWaitingPopup];
        BSPurchaseViewController *purchaseViewController = [segue destinationViewController];
        purchaseViewController.pngImage = [BSSharedObject getInstance].createdImage;


 NSLog(@"2");
    });

    dispatch_release(group);

}
}

私はまだ NSLog(@"2"); を取得します。3番目の NSInvocationOperation で画像を保存する前に

4

4 に答える 4

3

dispatch_group_async()GCD を使用して非同期タスクを実行する場合は、この関数を使用できます: Grand Central Dispatch (GCD) リファレンス

dispatch_group_t group = dispatch_group_create();

dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), 
^{
     //Code here is executed asynchronously
});

dispatch_group_notify(group, dispatch_get_main_queue(), 
^{
   //Do something when async has completed
   //Note: You are not required to use the main 
   //queue if you aren't performing any UI work.
});

dispatch_release(group);
于 2012-10-08T22:50:16.737 に答える
1

メイン スレッドに NSNotification を送信する最初の 3 つの操作に依存する 4 つ目の操作を追加します。何かのようなもの

NSOperation * completionOp = [NSBlockOperation blockOperationWithBlock:^{
  dispatch_async(dispatch_get_main_queue(), ^{
    [[NSNotificationCenter defaultCenter] postNotificationName:MyOperationsCompletedNotification object:... userInfo:nil];
  });
}];
[completionOp addDependency:op1];
[completionOp addDependency:op2];
[completionOp addDependency:op3];
[opQueue addOperation:op1];
[opQueue addOperation:op2];
[opQueue addOperation:op3];
[opQueue addOperation:completionOp];

object フィールドに nil 以外のものを入力したい場合があるため、コードに a を残しました...(ただし、スレッドセーフであると文書化されているものを除き、UIKit クラスであってはなりません)。

dispatch_async()あるいは、各操作はまたはを介し​​て結果を返すこともできます-performSelectorOnMainThread:が、繰り返しになりますが、スレッドセーフでない UIKit クラスのインスタンスをブロックで (または のレシーバーまたはオブジェクトとして-performSelectorOnMainThread:) 参照することは賢明ではありません。

これを行う方法はたくさんありますが、GameKit の例ではスレッドセーフでないと具体的に述べられています。特に、 UIView または UIViewController で呼び出される可能性のあるものはすべて、バックグラウンド スレッドで呼び出される-release可能性があるため、危険です。-dealloc

于 2012-10-08T23:25:09.857 に答える
0

キー値の監視を使用して、のisFinishedプロパティを監視できますsaveImageOperation

于 2012-10-08T23:44:05.633 に答える