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

时间:2012-09-07 23:44:32

标签: 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
    }
}

问题:

  

如果用户在上述循环中间的某处单击Quit   循环的其余必须在之前执行,它再次检查BOOL并最终停止。为了防止这种情况发生   发生并让用户点击后立即停止   退出,我想我也可以添加很多 if(quitButtonPressed) break;   在我的while循环中此处以便半持续检查并且“立即”在需要时脱离。但是,这似乎不是   鉴于 size ,从设计角度来看非常聪明或实用   上面的主要while循环以及它包含更小的事实   while-loops 在其中(我需要if.. break;的数量   添加会很大,可能会使事情变得非常复杂   弄清楚..)

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

  

所以我认为最好的方法是停止/取消   上面方法的while循环执行的后台线程,   而不是while循环本身,在方法内,当下   用户点击退出

     

这是或类似的东西(即更好的建议),可能和   我怎么能这样做?

可能实施上述解决方案:

我可以创建这个新方法:

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

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

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

正在执行游戏 while循环另一个,而循环同时检查QuitButton。但有没有一种方法可以实际调用以取消在此处开始的内容:

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

1 个答案:

答案 0 :(得分:6)

正确的解决方案是定期检查“停止”标志。突然终止一个线程没有提供清理资源的机会。简而言之,你会非常泄密。

但更深层次的问题是你几乎肯定不应该有这种线索。它强烈暗示了不正确的设计。在iOS中,大多数后台操作应采用集中操作的形式,使用NSOperation或使用Grand Central Dispatch执行。你应该非常非常需要一个执行许多不同类型功能的长寿命线程。在你的操作中,在“检查取消”语句的位置应该相当简单。

几乎不存在使用performSelectorInBackground:的情况。这是一种非常危险的方法,让你几乎无法控制。相反,请阅读Concurrency Programming Guide以获取有关如何正确实施后台操作的指导。请特别注意“远离线程迁移”一节。