Has*_*mad 13 nsoperation nsoperationqueue grand-central-dispatch ios objective-c-blocks
我有这些方法从互联网上检索一些对象信息:
- (void)downloadAppInfo:(void(^)())success
failure:(void(^)(NSError *error))failure;
- (void)getAvailableHosts:(void(^)())success
failure:(void(^)(NSError *error))failure;
- (void)getAvailableServices:(void(^)())success
failure:(void(^)(NSError *error))failure;
- (void)getAvailableActions:(void(^)())success
failure:(void(^)(NSError *error))failure;
Run Code Online (Sandbox Code Playgroud)
下载的东西存储在对象属性中,这就是成功函数不返回任何内容的原因.
现在,我想要一个像这样的方法:
- (void)syncEverything:(void(^)())success
failure:(void(^)(NSError *error))failure;
Run Code Online (Sandbox Code Playgroud)
除了调用上面的所有方法之外,它只会在每个方法执行其成功或失败块之后返回.
我怎样才能做到这一点?
提示:我知道级联方法调用彼此成功块会起作用.但是,当后来的实现包括更多方法时,这既不"干净"也不有用.
尝试:
我尝试在a中运行每个调用NSOperation并将其添加NSOperations到a NSOperationQueue后跟"完成操作",这取决于前面的每个操作.
这不行.由于即使在各自的成功/失败块返回之前也认为操作已完成.
我也试过用dispatch_group.但我不清楚我是以正确的方式做到这一点.不幸的是,它没有用.
pka*_*amb 15
从这里的其他答案的评论中得出,以及博客文章使用调度组等待多个Web服务,我得出了以下答案.
此解决方案使用dispatch_group_enter和dispatch_group_leave确定每个中间任务何时运行.完成所有任务后,将dispatch_group_notify调用最后一个块.然后,您可以调用完成块,知道所有中间任务都已完成.
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
[self yourBlockTaskWithCompletion:^(NSString *blockString) {
// ...
dispatch_group_leave(group);
}];
dispatch_group_enter(group);
[self yourBlockTaskWithCompletion:^(NSString *blockString) {
// ...
dispatch_group_leave(group);
}];
dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
// All group blocks have now completed
if (completion) {
completion();
}
});
Run Code Online (Sandbox Code Playgroud)
https://developer.apple.com/documentation/dispatch/dispatchgroup
分组块允许聚合同步.您的应用程序可以提交多个块并跟踪它们是否全部完成,即使它们可能在不同的队列上运行.在完成所有指定任务之前无法进行此操作时,此行为很有用.
我发现自己使用了Dispatch Groups,我已经将以下代码添加为Xcode片段,以便于插入到我的代码中.
现在我输入DISPATCH_SET并插入以下代码.然后,为每个异步块复制并粘贴enter/ leave.
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
dispatch_group_leave(group);
dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
});
Run Code Online (Sandbox Code Playgroud)
mic*_*tox 10
你几乎就在那里,问题很可能是那些方法是异步的,所以你需要一个额外的同步步骤.试试以下修复:
for(Appliance *appliance in _mutAppliances) {
dispatch_group_async(
group,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_semaphore_t sem = dispatch_semaphore_create( 0 );
NSLog(@"Block START");
[appliance downloadAppInfo:^{
NSLog(@"Block SUCCESS");
dispatch_semaphore_signal(sem);
}
failure:^(NSError *error){
NSLog(@"Block FAILURE");
dispatch_semaphore_signal(sem);
}];
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
NSLog(@"Block END");
});
dispatch_group_notify(
group,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
NSLog(@"FINAL block");
success();
});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7218 次 |
| 最近记录: |