调度组未阻止来自 运行 的代码
Dispatch Group not blocking code from running
我希望调度组中的代码在任何其他事情发生之前完成执行,实质上是阻止应用程序执行任何操作,直到此代码完成。但是,我无法让调度组阻止来自 运行 的附加代码。我已经尝试了这里关于堆栈的几乎所有建议,但我不知道我在做什么。
我的函数:
- (void)myFunction {
NSString *myString = @"Hello world";
dispatch_group_t group = dispatch_group_create();
NSLog(@"1 entering the dispatch group");
dispatch_group_enter(group);
[self doSomething:myString completion:^{
dispatch_group_leave(group);
NSLog(@"2 we have left the dispatch group");
}];
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"3 notifying that the dispatch group is finished");
}];
NSLog(@"4 all process are complete, we are done");
}
我想要通过日志语句输出 = 1,2,3,4
我通过日志语句得到的输出 = 1,4,2,3
为什么我的代码跳过调度组并在 2 和 3 之前打印 4?对我做错了什么的任何建议表示赞赏。谢谢!
更新:
这是我的 doSomething
方法。我的代码一直挂在 dismiss
调用上。
doSomething() {
viewController.dismiss(animated: false completion: { [weak self] in
doMoreCode()
})
}
这里没有任何东西真正阻止。 dispatch_group_notify
只是说 "when the group finishes, run this." 您打算使用的工具是 dispatch_group_wait
。如果你想要 1,2,3,4,那么你的意思是:
- (void)myFunction {
NSString *myString = @"Hello world";
dispatch_group_t group = dispatch_group_create();
NSLog(@"1 entering the dispatch group");
dispatch_group_enter(group);
[self doSomething:myString completion:^{
NSLog(@"2 we have left the dispatch group");
dispatch_group_leave(group);
}];
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog(@"3 notifying that the dispatch group is finished");
NSLog(@"4 all process are complete, we are done");
}
myFunction
当然不能在 iOS 中的主队列上调用(因为它会阻塞并且您绝不能阻塞主队列)。而且它也不能在 doSomething:completion:
用于其完成处理程序的同一队列上调用(因为该队列将在 dispatch_group_wait
处被阻塞)。
请记住,dispatch_queue_notify
只是将一个块添加到队列中,以便在将来的某个时间成为 运行。所以有点不清楚你期望 3 和 4 是如何工作的(在我的例子中我只是折叠它们,但也许你正在寻找其他东西)。
另一种方法是 不 阻止应用程序,只在应该的时候将内容安排到 运行。在这种情况下,您可以使用主队列。它看起来像这样:
- (void)myFunction {
NSString *myString = @"Hello world";
dispatch_group_t group = dispatch_group_create();
NSLog(@"1 entering the dispatch group");
dispatch_group_enter(group);
[self doSomething:myString completion:^{
NSLog(@"2 we have left the dispatch group");
dispatch_group_leave(group);
}];
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"3 notifying that the dispatch group is finished");
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"4 all process are complete, we are done");
});
}
请注意,在这两个示例中,我在调用 dispatch_group_leave
之前记录了 2。在此示例中,我还在组完成后(按顺序)在主队列上注册了两个要 运行 的东西。在这种情况下,myFunction
将立即 return(因此它可以在主队列上 运行),但所有内容都应按顺序打印出来。
假设 doSomething
异步运行,您可以等待该组,但通常最好采用异步模式,例如允许 myFunction
立即到 return,但要为该方法提供您自己的完成处理程序:
- (void)myFunctionWithCompletion:(void (^)())completion {
NSString *myString = @"Hello world";
dispatch_group_t group = dispatch_group_create();
NSLog(@"1 entering the dispatch group");
dispatch_group_enter(group);
[self doSomething:myString completion:^{
dispatch_group_leave(group);
NSLog(@"2 we have left the dispatch group");
}];
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"3 notifying that the dispatch group is finished");
});
}
并像这样使用它:
[self myFunctionWithCompletion:^{
NSLog(@"4 all process are complete, we are done");
}];
// note, it's not done when it gets here, though, because it's asynchronous
显然,在上面的例子中,调度组完全是多余的,但我假设你在做多个异步任务,这就是你引入调度组的原因。如果它真的只是一个异步任务,你就可以这样做:
- (void)myFunctionWithCompletion:(void (^)())completion {
NSString *myString = @"Hello world";
[self doSomething:myString completion:^{
NSLog(@"The asynchronous doSomething is done");
completion();
}];
}
我希望调度组中的代码在任何其他事情发生之前完成执行,实质上是阻止应用程序执行任何操作,直到此代码完成。但是,我无法让调度组阻止来自 运行 的附加代码。我已经尝试了这里关于堆栈的几乎所有建议,但我不知道我在做什么。
我的函数:
- (void)myFunction {
NSString *myString = @"Hello world";
dispatch_group_t group = dispatch_group_create();
NSLog(@"1 entering the dispatch group");
dispatch_group_enter(group);
[self doSomething:myString completion:^{
dispatch_group_leave(group);
NSLog(@"2 we have left the dispatch group");
}];
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"3 notifying that the dispatch group is finished");
}];
NSLog(@"4 all process are complete, we are done");
}
我想要通过日志语句输出 = 1,2,3,4
我通过日志语句得到的输出 = 1,4,2,3
为什么我的代码跳过调度组并在 2 和 3 之前打印 4?对我做错了什么的任何建议表示赞赏。谢谢!
更新:
这是我的 doSomething
方法。我的代码一直挂在 dismiss
调用上。
doSomething() {
viewController.dismiss(animated: false completion: { [weak self] in
doMoreCode()
})
}
这里没有任何东西真正阻止。 dispatch_group_notify
只是说 "when the group finishes, run this." 您打算使用的工具是 dispatch_group_wait
。如果你想要 1,2,3,4,那么你的意思是:
- (void)myFunction {
NSString *myString = @"Hello world";
dispatch_group_t group = dispatch_group_create();
NSLog(@"1 entering the dispatch group");
dispatch_group_enter(group);
[self doSomething:myString completion:^{
NSLog(@"2 we have left the dispatch group");
dispatch_group_leave(group);
}];
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog(@"3 notifying that the dispatch group is finished");
NSLog(@"4 all process are complete, we are done");
}
myFunction
当然不能在 iOS 中的主队列上调用(因为它会阻塞并且您绝不能阻塞主队列)。而且它也不能在 doSomething:completion:
用于其完成处理程序的同一队列上调用(因为该队列将在 dispatch_group_wait
处被阻塞)。
请记住,dispatch_queue_notify
只是将一个块添加到队列中,以便在将来的某个时间成为 运行。所以有点不清楚你期望 3 和 4 是如何工作的(在我的例子中我只是折叠它们,但也许你正在寻找其他东西)。
另一种方法是 不 阻止应用程序,只在应该的时候将内容安排到 运行。在这种情况下,您可以使用主队列。它看起来像这样:
- (void)myFunction {
NSString *myString = @"Hello world";
dispatch_group_t group = dispatch_group_create();
NSLog(@"1 entering the dispatch group");
dispatch_group_enter(group);
[self doSomething:myString completion:^{
NSLog(@"2 we have left the dispatch group");
dispatch_group_leave(group);
}];
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"3 notifying that the dispatch group is finished");
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"4 all process are complete, we are done");
});
}
请注意,在这两个示例中,我在调用 dispatch_group_leave
之前记录了 2。在此示例中,我还在组完成后(按顺序)在主队列上注册了两个要 运行 的东西。在这种情况下,myFunction
将立即 return(因此它可以在主队列上 运行),但所有内容都应按顺序打印出来。
假设 doSomething
异步运行,您可以等待该组,但通常最好采用异步模式,例如允许 myFunction
立即到 return,但要为该方法提供您自己的完成处理程序:
- (void)myFunctionWithCompletion:(void (^)())completion {
NSString *myString = @"Hello world";
dispatch_group_t group = dispatch_group_create();
NSLog(@"1 entering the dispatch group");
dispatch_group_enter(group);
[self doSomething:myString completion:^{
dispatch_group_leave(group);
NSLog(@"2 we have left the dispatch group");
}];
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"3 notifying that the dispatch group is finished");
});
}
并像这样使用它:
[self myFunctionWithCompletion:^{
NSLog(@"4 all process are complete, we are done");
}];
// note, it's not done when it gets here, though, because it's asynchronous
显然,在上面的例子中,调度组完全是多余的,但我假设你在做多个异步任务,这就是你引入调度组的原因。如果它真的只是一个异步任务,你就可以这样做:
- (void)myFunctionWithCompletion:(void (^)())completion {
NSString *myString = @"Hello world";
[self doSomething:myString completion:^{
NSLog(@"The asynchronous doSomething is done");
completion();
}];
}