1

我在 prepareForSegue 回调中有 NSOperationQueue 和 3 NSInvocationOperation ,我需要在完成所有异步任务后移动到另一个视图控制器。只有在移动到另一个屏幕之后,我才能收到关于完成所有异步任务的通知?

我试过这个没有成功:

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"); 早于我在第三个 NSInvocationOperation 中保存图像

4

4 回答 4

3

dispatch_group_async()如果您打算使用 GCD 执行异步任务,则可以使用该功能: Grand Central Dispatch (GCD) Reference

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 的前三个操作。就像是

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];

...在代码中留下了 a ,因为您可能想用 nil 以外的东西填充对象字段(但它不应该是 UIKit 类,除了那些被记录为线程安全的类)。

或者,每个操作都可以通过 adispatch_async()或返回其结果-performSelectorOnMainThread:,但同样,在块中引用线程不安全的 UIKit 类的实例(或作为 a 的接收者或对象-performSelectorOnMainThread:)是不明智的。

有很多方法可以做到这一点,这些方法在 GameKit 示例中被特别提到是线程不安全的——特别是,任何可能最终调用-releaseUIView 或 UIViewController 的方法都是危险的,因为这可能会导致-dealloc在后台线程上调用。

于 2012-10-08T23:25:09.857 回答
1

您可以在Swift 3+中使用 GCD dispatch_group来实现这一点。当所有任务完成时,您会收到通知。

let group = DispatchGroup()

    group.enter()
    run(after: 6) {
      print(" 6 seconds")
      group.leave()
    }

    group.enter()
    run(after: 4) {
      print(" 4 seconds")
      group.leave()
    }

    group.enter()
    run(after: 2) {
      print(" 2 seconds")
      group.leave()
    }

    group.enter()
    run(after: 1) {
      print(" 1 second")
      group.leave()
    }


    group.notify(queue: DispatchQueue.global(qos: .background)) {
      print("All async calls completed")
}
于 2017-06-15T08:53:26.137 回答
0

isFinished您可以使用键值观察来观察saveImageOperation.

于 2012-10-08T23:44:05.633 回答