objective-c - 如何突然停止当前在后台执行的线程?

标签 objective-c ios multithreading while-loop

事实:

我有一个在后台线程上执行的方法:

[currentGame performSelectorInBackground:@selector(playOn:) withObject:self];

此方法基本上包含一个 while 循环,该循环一直执行到用户单击退出 按钮为止:

-(void) playOn: (UIViewController*) thisViewController
{
    while(!quitButtonPressed)
    {
       // this is my method's main loop
    }
}

问题:

If the user clicks on Quit somewhere in the middle of the above loop the rest of the loop would have to execute before it checks the BOOL once again and eventually stops. In order to prevent that from happening and have the while-loop stop as soon as the user clicks on Quit, I guess I could also add many if(quitButtonPressed) break; here and there in my while loop in order to semi-constantly check and "immediately" break away if needed. However, this doesn't seem very clever or practical from a design perspective given the size of the above main while-loop and the fact that it contains many smaller while-loops inside of it (the number of if.. break; I would have to add would be quite big and could make things quite complicated to figure out..)

可能的解决方案(但它是正确的吗?):

So I was thinking that the best way would be to stop/cancel the background thread on which the above method's while loop is executing, instead of the while-loop itself, inside the method, the moment the user clicks on Quit

Is this, or something similar (i.e. a better suggestion), possible and how exactly could I do this?

上述解决方案的可能实现方式:

我可以创建这个新方法:

-(void)checkQuitButton
{
   while(!quitButtonPressed)
   {
      //wait
   }
   if(quitButtonPressed)
   {
     // stop this thread-->[currentGame performSelectorInBackground:@selector(playOn:) withObject:self];
     // this is the method I'm looking for
   }
}

然后我可以开始在两个单独的后台线程上同时执行上面的和我之前的主要方法,如下所示:

[currentGame performSelectorInBackground:@selector(playOn:) withObject:self];
[currentGame performSelectorInBackground:@selector(checkQuitButton) withObject:nil];

game while-loop 正在执行时,另一个 while-loop 正在同时检查 QuitButton。但是有没有一种方法我可以实际调用以取消此处开始的内容:

[currentGame performSelectorInBackground:@selector(playOn:) withObject:self];

?

最佳答案

正确的解决方案是定期检查“停止”标志。突然终止线程不会提供清理资源的机会。简而言之,您会严重泄漏内存。

但更深层次的问题是你几乎肯定不应该有这种线程。它强烈建议不正确的设计。在 iOS 中,大多数后台操作应该采用聚焦操作的形式,使用 NSOperation 或使用 Grand Central Dispatch 的 block 来实现。您应该非常、非常少地需要执行许多不同类型功能的长生命周期线程。在您的操作中,放置“检查取消”语句的位置应该相当简单。

也几乎没有您应该使用 performSelectorInBackground: 的情况。这是一种非常危险的方法,几乎​​无法控制。相反,请阅读 Concurrency Programming Guide有关如何正确实现后台操作的指导。请特别注意“从线程迁移”部分。

关于objective-c - 如何突然停止当前在后台执行的线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12326745/

相关文章:

ios - objective-c -检查NSString是否可计算

ios - Xamarin Forms iOS AdMobViewRenderer VS2019

iphone - AQGridView 背景图片

ios - 当参与者快速加入时,不会调用 ooVooAVChatDelegate

c# - 使用 Threads C# 制作的聊天服务器的 CPU 使用率 100%

C 中的转换问题

iphone - 根据子对象的属性对对象进行排序

ios - 以奇怪的行为一次关闭多个 View Controller

objective-c - 旋转到横向后 iOS 边界发生变化,然后返回纵向

c - 如何将 for 循环的索引作为 pthread_create 的参数传递