事实:
我有一个在后台线程上执行的方法:
[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];
答案 0 :(得分:6)
正确的解决方案是定期检查“停止”标志。突然终止一个线程没有提供清理资源的机会。简而言之,你会非常泄密。
但更深层次的问题是你几乎肯定不应该有这种线索。它强烈暗示了不正确的设计。在iOS中,大多数后台操作应采用集中操作的形式,使用NSOperation
或使用Grand Central Dispatch执行。你应该非常非常需要一个执行许多不同类型功能的长寿命线程。在你的操作中,在“检查取消”语句的位置应该相当简单。
几乎不存在使用performSelectorInBackground:
的情况。这是一种非常危险的方法,让你几乎无法控制。相反,请阅读Concurrency Programming Guide以获取有关如何正确实施后台操作的指导。请特别注意“远离线程迁移”一节。