2016-05-31 78 views
1

在客观C, 我让我的程序中使用while循环在iOS编程中使用while(true)语句是一种有效的方法?

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

忙碌的等待是一个可怕的想法。为什么你要在后台运行这个更新功能? – Thilo

+0

如果你使用异步路由,dispatch_groups有什么问题? – Thilo

+1

假设RenewAuthTokenInProgress保持一段时间,然后是你的iPhone会变热。您将以100%运行其中一个内核。它也会使你的电池变平。 – TJA

回答

6

的Manoj库马尔,

使用while循环要等到布尔变量的变化是不是解决问题的正确途径。这里有几个这个方法的问题

  1. 你的CPU是不必要的负担有定期检查变量。

  2. 这将清楚地表明,开发人员没有太多配备编程和语言功能的基本技能。

  3. 如果因为任何原因你的变量永远不会改变,那么你的CPU永远不会停止检查while循环中的bool值,并阻止在同一线程上执行进一步的代码。

这里有一些正确的方法:

  1. 块或倒闭:利用块来当RenewAuthToken完成异步执行代码。

  2. 代表:如果块更难理解,请在完成RenewAuthToken时使用委托并触发委托。

  3. 通知:为需要在RenewAuthToken完成时需要响应的类添加通知的观察者,并从异步抽出通知并让类捕获它执行代码。

  4. 锁:如果有必要,直到响应来使用锁来控制线程执行,而不是使用以阻止线程的执行while循环

EDIT

如尖由fogmeister在评论

如果您阻止主线程太长时间(true)循环然后 应用程序实际上将iOS的看门狗被终止,因为它会 假设它已经崩溃

请看看链接:通过提供fogmeister understand iOS watchdog termination reasons

希望它能帮助。

+3

还有一些要注意的事情。如果使用'while(true)'循环阻塞主线程时间过长,那么应用程序实际上将被iOS Watchdog终止,因为它会认为它已经崩溃。 – Fogmeister

+0

@fogmeister:Bingo :)投票支持:) –

+1

如果你想要添加一个链接https://developer.apple.com/library/ios/technotes/tn2151/_index.html搜索'8badf00d'会显示看门狗终止的原因。 – Fogmeister

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; 
     }); 
    } 
} 

}); 

信号灯是由曾经那么卑微艾兹赫尔·戴克斯特拉介绍给世界一个老派的线程概念。信号量是一个复杂的话题,因为它们建立在操作系统功能的复杂性之上。

你可以在这里看到一个教程的信号,并检查了更多的链接:https://www.raywenderlich.com/63338/grand-central-dispatch-in-depth-part-2

我希望这可以帮助你。

+0

没有冒犯,但信号灯通常是懒惰不处理异步模式的处理的证据。 – vadian

+1

没有冒犯,但信号灯往往是一个处理异步事件的好方法。对于这个特定的问题,尽管很可能不是正确的选择。还有一种先进技术,可能超出OP。 – gnasher729

+0

有没有进攻,谢谢你的两个意见,我相信这是相当意见,我同意gnasher729,但我真的明白你的意思vadian。 –

0

你所做的绝对是致命的。它阻止正在运行的线程(可能是主线程),因此UI被冻结。它在100%的负载下运行一个内核,没有任何理由使电池快速排空并加热电话。这会让你有些非常非常不开心的顾客,或者非常非常开心的前顾客。

像这样的任何东西都必须在后台运行:startRenewThread应该触发一些设置RenewAuthTokenInProgress = NO的动作,并设置是否有新的令牌,然后触发进一步的动作。

这是一个绝对必要的编程模式在iOS(和我所知的Android)上。

相关问题