在目标C中, 我让我的程序等待使用while循环
doInitialize()
{
dispach_group_t loadDataGroup=dispatch_group_create();
dispatch_group_async(loadDataGroup,...get_global_queue(..),0),^{
renewauth();
}
dispatch_group_notify(loadDataGroup,...get_global_queue(..),0),^{
//Do other tasks once renew session has completed...
}
}
renewauth()
{
RenewAuthTokenInProgress=true;
startRenewThread();
**while (RenewAuthTokenInProgress);**
}
反过来startRenewThread()函数也在里面执行dispatch_async操作。所以我必须让renewAuth()等待。
一旦续订成功,startRenewThread中的异步任务将更新bool变量。
除了dispatch_groups之外,还有更好的方法吗? 并且让其他线程等待while(true)语句是好的吗?
答案 0 :(得分:6)
Manoj Kumar,
使用while循环等待布尔变量更改不是解决问题的正确方法。以下是此方法的一些问题
您的CPU不一定要经常检查变量。
这将清楚地表明,开发人员没有太多的编码基本技能和语言功能。
如果由于任何原因你的变量永远不会改变,那么你的CPU永远不会停止检查while循环中的bool值,并阻止在同一个线程上执行更多代码。
以下是一些正确的方法:
阻止或关闭:在RenewAuthToken完成后,使用块来异步执行代码。
代表:如果很难理解块,请使用委托并在完成RenewAuthToken后触发委托。
通知:在RenewAuthToken完成时需要响应的类中添加通知观察者,并从asynctask中抛出通知并让类捕获它来执行代码。
锁定:如果有必要阻止执行线程直到响应到来,请使用锁来控制线程执行而不是使用while循环
修改强>
正如评论中的fogmeister所指出的
如果使用while(true)循环阻塞主线程太长时间 该应用程序实际上将由iOS Watchdog终止 假设它已经崩溃
请查看由fogmeister提供的链接:understand iOS watchdog termination reasons
希望它有所帮助。
答案 1 :(得分:1)
我相信你需要的是semaphore
喜欢:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
__block BOOL done = FALSE;
while (true) {
[self someCompletionMethod completion:^(BOOL success) {
if(success) { // Stop condition
done = TRUE;
}
// do something
dispatch_semaphore_signal(sem); // This will let a new iteration
}];
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
if(done) {
dispatch_async(dispatch_get_main_queue(), ^{
// Dispatch to main
NSLog(@"Done!");
break;
});
}
}
});
信号量是一种老式的线程概念,由不断谦逊的Edsger W. Dijkstra引入世界。信号量是一个复杂的主题,因为它们建立在操作系统功能的复杂性之上。
您可以在此处查看有关信号量的教程,并查看更多链接:https://www.raywenderlich.com/63338/grand-central-dispatch-in-depth-part-2
我希望这可以帮到你。
答案 2 :(得分:0)
你做的是绝对致命的。它阻止正在运行的线程(可能是主线程),因此UI被冻结。它以100%的负载运行一个核心,无论如何都会快速清空电池并加热电话。这将为您带来一些非常非常不满意的客户或非常非常快乐的前客户。
这样的事情必须在后台运行:startRenewThread应该触发一些设置RenewAuthTokenInProgress = NO的动作,并设置是否有新的令牌,然后触发进一步的动作。
这是iOS上的绝对必要的编程模式(据我所知,Android)。