2

事实:

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

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

这个方法基本上包含一个 while 循环,它会一直执行,直到用户单击Quit按钮:

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

问题:

如果用户在上述循环中间的某处单击退出,则循环 的其余部分必须在再次检查 BOOL 并最终停止之前执行。为了防止这种情况发生并在用户单击退出时立即停止 while 循环,我想我还可以在我的 while 循环中到处添加许多 ,以便半持续地检查并“立即”脱离如果需要的话。然而,考虑到上述主 while 循环的大小以及它包含许多较小的 while 循环的事实,从设计的角度来看,这似乎不是很聪明或实用if(quitButtonPressed) break; 在其中(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 循环正在执行时,另一个while 循环同时检查 QuitButton。但是有没有一种我可以实际调用的方法来取消这里开始的操作:

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

?

4

1 回答 1

6

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

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

也几乎没有你应该使用performSelectorInBackground:. 这是一种极其危险的方法,几乎​​无法控制。相反,请阅读并发编程指南以获取有关如何正确实现后台操作的指导。请特别注意“从线程迁移”部分。

于 2012-09-08T00:21:20.600 回答