在我的应用中,我在后台运行服务器。我使用NSOperation
来执行此操作。 (之前我使用过GCD,但我需要能够阻止它,所以我切换到NSOperation
,但我仍然无法弄清楚如何。)
基本上,我的NSOperation
子类看起来像这样:
- (void)main {
server_main(var1, var2);
}
由于这是一个服务器,server_main
函数基本上不会返回。我也无法控制该功能的实现。
有时,用户会更改服务器的设置。发生这种情况时,我想停止然后重新启动服务器。如果我理解正确,我需要在if (self.isCancelled)
子类中执行NSOperation
之类的操作,但由于它会卡在server_main
函数中,我怀疑它是否真的有效。
那我怎么能停止服务器?
非常感谢!
答案 0 :(得分:2)
要正确执行此操作,请参阅并发编程指南中的Responding to Cancellation Events,其中包含:
虽然
NSOperation
类为客户提供取消操作的方法,但必须自愿识别取消事件。如果操作被彻底终止,则可能无法回收已分配的资源。因此,操作对象应检查取消事件,并在操作过程中正常退出。要支持在操作对象中取消,您只需要定期从自定义代码调用对象的
isCancelled
方法,如果它返回YES
则立即返回。
这是一个冗长的方式,说我真的认为你需要能够改变server_main
以便它:
定期检查isCancelled
或
让它提供一个回调/进度委托方法块,这样你就可以自己做了,还可以调用一些额外的函数/方法取消server_main
,让它进入关键的清理过程。
如果您刚开始查杀进程(如果可以的话),您无疑会泄漏资源或使server_main
处于不一致状态。
我知道这不是您正在寻找的答案,但这是取消操作的方式。遗憾。
答案 1 :(得分:0)
你可以使用
- (void)setSuspended:(BOOL)suspend
NSOperationQueue上的方法?在添加新操作之前,请检查队列是否已使用isSuspended挂起?
修改:此处参数暂停 如果是,则队列停止调度排队操作以执行。如果为NO,则队列再次开始调度操作。 讨论 此方法暂停或恢复操作的执行。挂起队列会阻止该队列启动其他操作。换句话说,在队列恢复之前,阻止队列中的操作(或稍后添加到队列中)并且尚未执行的操作开始。挂起队列不会停止已经运行的操作。
只有在完成执行后才会从队列中删除操作。但是,为了完成执行,必须首先启动操作。由于挂起的队列不会启动任何新操作,因此它不会删除当前已排队且未执行的任何操作(包括已取消的操作)。
希望它对你有所帮助。
答案 2 :(得分:0)
您可以尝试以下代码:
@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);}
});
}
希望它有所帮助。