[英]Force stop a NSOperation or GCD?
在我的应用程序中,我在后台运行服务器。 我正在使用NSOperation
这样做。 (之前我使用过GCD,但我需要能够阻止它,所以我切换到NSOperation
,但我仍然无法弄明白。)
基本上,我的NSOperation
子类看起来像这样:
- (void)main {
server_main(var1, var2);
}
由于这是一个服务器, server_main
函数基本上不返回。 我也无法控制该功能的实现。
有时,用户会更改服务器的设置。 发生这种情况时,我想停止然后重新启动服务器。 如果我理解正确,我需要在NSOperation
子类中执行if (self.isCancelled)
之类的操作,但由于它将卡在server_main
函数中,我怀疑它实际上是否有效。
那我怎么能停止服务器呢?
非常感谢!
要正确执行此操作,请参阅“ 并发编程指南”中的“ 响应取消事件 ”,其中说明:
尽管
NSOperation
类为客户提供了取消操作的方法,但必须自愿识别取消事件。 如果操作被彻底终止,则可能无法回收已分配的资源。 因此,操作对象应检查取消事件,并在操作过程中发生时正常退出。要支持操作对象的取消,您只需要定期从自定义代码调用对象的
isCancelled
方法,如果它返回YES
则立即返回。
这是一个冗长的方式,说我真的认为你需要能够更改server_main
以便它:
定期检查isCancelled
,或
让它提供一个回调/进度委托方法块,这样你就可以自己完成,也可以调用一些额外的函数/方法来取消server_main
,让它进入关键的清理过程。
如果您刚开始查杀进程(如果可以的话),您无疑会泄漏资源或使该server_main
处于不一致状态。
我知道这不是您正在寻找的答案,但这是取消操作的方式。 抱歉。
你可以使用
- (void)setSuspended:(BOOL)suspend
NSOperationQueue上的方法? 在添加新操作之前,检查队列是否已使用isSuspended挂起?
编辑:此处参数suspend如果是,则队列停止调度排队操作以执行。 如果为NO,则队列再次开始调度操作。 讨论此方法暂停或恢复操作的执行。 挂起队列会阻止该队列启动其他操作。 换句话说,在队列恢复之前,阻止队列中的操作(或稍后添加到队列中)并且尚未执行的操作开始。 挂起队列不会停止已在运行的操作。
只有在完成执行后才会从队列中删除操作。 但是,为了完成执行,必须首先启动操作。 由于挂起的队列不会启动任何新操作,因此它不会删除当前已排队且未执行的任何操作(包括已取消的操作)。
希望它能帮到你。
你可以试试这段代码:
@interface Canceller
{
BOOL _shouldCancel;
}
- (void)setShouldCancel:(BOOL)shouldCancel;
- (BOOL)shouldCancel;
@end
@implementation Canceller
- (void)setShouldCancel:(BOOL)shouldCancel {
_shouldCancel = shouldCancel;
}
- (BOOL)shouldCancel {
return _shouldCancel;
}
@end
static void test(int a){
static Canceller * canceller = nil;
if(q){
[canceller setShouldCancel:YES];
[canceller release];
dispatch_suspend(q);
dispatch_release(q);
q=nil;
}
canceller = [[Canceller alloc] init];
q=dispatch_get_global_queue(0,0);
dispatch_async(q,^ {
while(![canceller shouldCancel]){NSLog(@"query %d",a);sleep(2);}
});
}
希望能帮助到你。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.