gpt4 book ai didi

objective-c - 等待条件继续

转载 作者:行者123 更新时间:2023-12-03 17:55:43 24 4
gpt4 key购买 nike

我有一个方法,可以将其添加到我创建的 GCD 队列中(因此它是一个串行队列),然后异步运行它。从该代码块中,我向主队列进行分派(dispatch),当分派(dispatch)到主队列的代码块完成时,我将 BOOL 标志设置为 YES,以便我在代码中进一步检查此条件是否为 YES然后我可以继续下一个方法。这是简短的代码:

dispatch_queue_t queue = dispatch_queue_create("ProcessSerialQueue", 0);

dispatch_async(queue, ^{

Singleton *s = [Singleton sharedInstance];

dispatch_sync(dispatch_get_main_queue(), ^{
[s processWithCompletionBlock:^{

// Process is complete
processComplete = YES;
}];
});
});

while (!processComplete) {

NSLog(@"Waiting");
}

NSLog(@"Ready for next step");

但是这不起作用,因为dispatch_sync永远无法在主队列上运行代码。这是因为我在主队列上运行 while 循环(使其繁忙)吗?

但是,如果我将 while 循环的实现更改为:

while (!processComplete) {

NSLog(@"Waiting")
NSDate *date = [NSDate distantFuture];
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:date];
}

它可以正常工作。对于这种情况,这是可接受的解决方案吗?我可以采用其他首选方式吗? NSRunLoop 做了什么神奇的事情?我需要更好地理解这一点。

最佳答案

主线程的 NSRunLoop 作业的一部分是运行在主线程上排队的任何 block 。通过在 while 循环中旋转,您可以阻止运行循环继续进行,因此除非您明确地自己运行循环,否则排队的 block 永远不会运行。

Runloops 是 Cocoa 的基本组成部分,而 documentation非常不错,推荐阅读。

通常,我会避免像您一样手动调用运行循环。如果您同时运行多个手动调用,则会浪费内存并使事情很快变得复杂。

但是,有一种更好的方法可以做到这一点。将您的方法拆分为 -process 和 -didProcess 方法。使用 -process 方法启动异步操作,当它完成时,从完成 block 调用 -didProcess 。如果您需要将变量从一种方法传递到另一种方法,您可以将它们作为参数传递给 -didProcess 方法。

例如:

dispatch_queue_t queue = dispatch_queue_create("ProcessSerialQueue", 0);

dispatch_async(queue, ^{
Singleton *s = [Singleton sharedInstance];

dispatch_sync(dispatch_get_main_queue(), ^{
[s processWithCompletionBlock:^{
[self didProcess];
}];
});
});

您还可以考虑让您的单例拥有调度队列并让它负责处理dispatch_async的东西,因为如果您总是异步使用它,它会节省所有那些讨厌的嵌入 block 。

例如:

[[Singleton sharedInstance] processAyncWithCompletionBlock:^{
NSLog(@"Ready for next step...");
[self didProcess];
}];

关于objective-c - 等待条件继续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13824394/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com