Objective C 等待带有信号量的循环块
ObjectiveC waiting on for loop blocks with semaphore
我必须 运行 一个 method
和 block
,在一个 for loop
里面好几次。
我还必须等到所有 blocks
执行完成。
我的问题是我无法理解我做错了什么,这导致我的整个应用程序冻结。这是代码:
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);//1 - creating semaphore
for(int i = 0; i< myObj.count; i++){
[[DataManager shared] verifyObjectId:myObj[i].id
completionBlock:^(BOOL found) {
if(found){
//code here
dispatch_semaphore_signal(semaphore);//3 - signaling semaphore to continue
}
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);//2 - getting semaphore to wait
}
//I want to continue once all DB checks complete
现在,我不明白,为什么semaphore
不发布,for loop
不继续
我真正需要的是 semaphore
在所有数据库检查完成后释放。理想情况下,我希望 semaphore
在 for loop
之外等待。关于如何实现这一点有什么建议吗?
编辑:解决方案:(基于已接受的答案)
// create a group
dispatch_group_t group = dispatch_group_create();
for(int i = 0; i< myObj.count; i++){
// pair a dispatch_group_enter for each dispatch_group_leave
dispatch_group_enter(group);
[[DataManager shared] verifyObjectId:myObj[i].id
completionBlock:^(BOOL found) {
if(found){
//code here
}
dispatch_group_leave(group); //1 leave
}];
//Get a notification on a block that will be scheduled on the specified queue
dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSLog(@"-all done!-");
//code here
});
}
无法访问 verifyObjectid:completiongBlock:
,有几个问题。首先,如果 found
为真,则只调用 dispatch_semaphore_signal
。如果 found
都是假的,你就会陷入僵局。这可能只是一个转录错误,您的真实代码可能不会这样做。
另一种猜测是,完成块正在提交到您当前 运行正在使用的队列(主队列?)如果这是真的,那肯定会出现死锁,因为您永远不会 运行 dispatch_semaphore_signal
因为它正在等待 dispatch_semaphore_wait
。没有关于 DataManager
.
的信息,我无法判断
您的方法还序列化调用,而我认为您希望它们是并行的。每个调用都必须等待前一个调用在您的代码中完成。
这里使用的更好的工具是 dispatch_apply
和 dispatch_group
。像这样(未经测试):
dispatch_group_t group = dispatch_group_create();
dispatch_apply(myObj.count, dispatch_get_global_queue(0, 0), ^(size_t i){
dispatch_group_enter(group);
[[DataManager shared] verifyObjectId:myObj[i].id
completionBlock:^(BOOL found) {
if(found){
//code here
}
dispatch_group_leave(group));
}];
});
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
dispatch_apply
不会 return 直到所有块都完成 运行ning,这意味着 dispatch_group_enter
有 运行 "count"次。然后使用 dispatch_group_wait
等待对 dispatch_group_leave
.
的所有调用
我必须 运行 一个 method
和 block
,在一个 for loop
里面好几次。
我还必须等到所有 blocks
执行完成。
我的问题是我无法理解我做错了什么,这导致我的整个应用程序冻结。这是代码:
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);//1 - creating semaphore
for(int i = 0; i< myObj.count; i++){
[[DataManager shared] verifyObjectId:myObj[i].id
completionBlock:^(BOOL found) {
if(found){
//code here
dispatch_semaphore_signal(semaphore);//3 - signaling semaphore to continue
}
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);//2 - getting semaphore to wait
}
//I want to continue once all DB checks complete
现在,我不明白,为什么semaphore
不发布,for loop
不继续
我真正需要的是 semaphore
在所有数据库检查完成后释放。理想情况下,我希望 semaphore
在 for loop
之外等待。关于如何实现这一点有什么建议吗?
编辑:解决方案:(基于已接受的答案)
// create a group
dispatch_group_t group = dispatch_group_create();
for(int i = 0; i< myObj.count; i++){
// pair a dispatch_group_enter for each dispatch_group_leave
dispatch_group_enter(group);
[[DataManager shared] verifyObjectId:myObj[i].id
completionBlock:^(BOOL found) {
if(found){
//code here
}
dispatch_group_leave(group); //1 leave
}];
//Get a notification on a block that will be scheduled on the specified queue
dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSLog(@"-all done!-");
//code here
});
}
无法访问 verifyObjectid:completiongBlock:
,有几个问题。首先,如果 found
为真,则只调用 dispatch_semaphore_signal
。如果 found
都是假的,你就会陷入僵局。这可能只是一个转录错误,您的真实代码可能不会这样做。
另一种猜测是,完成块正在提交到您当前 运行正在使用的队列(主队列?)如果这是真的,那肯定会出现死锁,因为您永远不会 运行 dispatch_semaphore_signal
因为它正在等待 dispatch_semaphore_wait
。没有关于 DataManager
.
您的方法还序列化调用,而我认为您希望它们是并行的。每个调用都必须等待前一个调用在您的代码中完成。
这里使用的更好的工具是 dispatch_apply
和 dispatch_group
。像这样(未经测试):
dispatch_group_t group = dispatch_group_create();
dispatch_apply(myObj.count, dispatch_get_global_queue(0, 0), ^(size_t i){
dispatch_group_enter(group);
[[DataManager shared] verifyObjectId:myObj[i].id
completionBlock:^(BOOL found) {
if(found){
//code here
}
dispatch_group_leave(group));
}];
});
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
dispatch_apply
不会 return 直到所有块都完成 运行ning,这意味着 dispatch_group_enter
有 运行 "count"次。然后使用 dispatch_group_wait
等待对 dispatch_group_leave
.