Ios 等待许多异步调用以执行回调
我想用web服务同步一些数据。对于每个项目,我必须进行异步调用 我想在同步每个项目时调用一个完成块。对于每一项,我都能执行一个完成块。现在,我不知道怎么做才好 这是接口:Ios 等待许多异步调用以执行回调,ios,objective-c,ios5,block,Ios,Objective C,Ios5,Block,我想用web服务同步一些数据。对于每个项目,我必须进行异步调用 我想在同步每个项目时调用一个完成块。对于每一项,我都能执行一个完成块。现在,我不知道怎么做才好 这是接口: -(void) synchronizeItemsOnComplete:(CompleteBlock) block { NSArray* items = // get items for (int i = 0, n = [items count]; i < n; i++) { [self sy
-(void) synchronizeItemsOnComplete:(CompleteBlock) block {
NSArray* items = // get items
for (int i = 0, n = [items count]; i < n; i++) {
[self synchronizeItem:[items objectAtIndex:i] onComplete:^{
// What do do here?
}];
}
// And/or here?
}
-(void) synchronizeItemOnComplete:(CompleteBlock) block {
// do something
block();
}
-(void)synchronizeItemsOnComplete:(CompleteBlock)块{
NSArray*items=//获取项目
对于(int i=0,n=[项目计数];i
如何等待同步,然后执行块
我试过这样的方法:
NSArray* items = // get items
__block int countOfItemsUntilDone = [items count];
for (int i = 0, n = countOfItemsUntilDone; i < n; i++) {
[self synchronizeItem:[items objectAtIndex:i] onComplete:^{
countOfItemsUntilDone--;
}];
}
dispatch_queue_t queue = dispatch_queue_create("wait for syncing", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
while (countOfItemsUntilDone > 0) {
usleep(1000); // wait a little bit
}
block();
});
dispatch_release(queue);
NSArray*items=//获取项目
__block int countOfItemsUntilDone=[items count];
for(int i=0,n=countOfItemsUntilDone;i0){
usleep(1000);//稍等
}
block();
});
调度释放(队列);
但我认为这是一个相当糟糕的方式。有什么想法吗?您可以使用这些想法同步使用 及
性能选择器:waitUntilDone:YES
不是在循环中旋转等待计数器等于零,而是在每次减小计数器值时检查它,然后在它达到零时触发事件
-(void) synchronizeItemsOnComplete:(CompleteBlock) block {
NSArray* items = // get items
__block NSUInteger remaining = [items count];
for (ItemClass* item in items) {
[self synchronizeItemImage:item onComplete:^{
--remaining;
if (remaining == 0) {
block();
}
}];
}
}
为了解释为什么感觉不对,这里有两件事你应该永远不要做或很少做:
- 使用后台队列。这很困难,而且容易出现错误。如果没有阅读大量关于编写并发代码的内容,就不要这样做。如果操作阻塞了相当长的时间(例如,从磁盘读取文件,或执行密集计算),您也确实需要这样做。除非你有充分的理由(例如,可测量的性能问题),否则不要认为你需要这样做
- 在循环中旋转,检查变量的变化并调用sleep。你不应该这样做
另外,如果在数组中的元素上循环,则。。。在中,在每个索引上调用objectAtIndex:的语法更好(而且可能更有效)。不要像这样检查或减少不同线程中的共享内存,这可能会导致争用。使用调度组执行您正在执行的操作
dispatch_queue_t myBGQueue;
dispatch_group_t itemsGroup = dispatch_group_create();
for (ItemClass *item in items) {
dispatch_group_async(itemsGroup, myBGQueue, ^{
[self synchronizeItemImage:item];
});
}
/* execution will sleep here until all the blocks added in the `for` complete */
dispatch_group_wait(itemsGroup, DISPATCH_TIME_FOREVER);
dispatch_release(itemsGroup);
哦我没有说清楚那一点。那个叫做synchronizeItemImage的方法通过RESTKit启动一个异步请求。因此,异步或使用
waitUntilDone:
执行该方法可能不起作用。为了避免减少不同线程中的共享内存,我可以在串行调度队列上执行Chris Devereux解决方案中的块,或者这也很糟糕?哦。在这种情况下,只要在主线程上调用完成处理程序,就可以减少一些变量。或者更好的方法是,减少windowController或应用程序委托上的属性,并使用KVO通知来确定它何时达到零。