强制停止NSOperation或GCD?

时间:2013-05-01 12:09:21

标签: ios nsoperation

在我的应用中,我在后台运行服务器。我使用NSOperation来执行此操作。 (之前我使用过GCD,但我需要能够阻止它,所以我切换到NSOperation,但我仍然无法弄清楚如何。)

基本上,我的NSOperation子类看起来像这样:

- (void)main {
    server_main(var1, var2);
}

由于这是一个服务器,server_main函数基本上不会返回。我也无法控制该功能的实现。

有时,用户会更改服务器的设置。发生这种情况时,我想停止然后重新启动服务器。如果我理解正确,我需要在if (self.isCancelled)子类中执行NSOperation之类的操作,但由于它会卡在server_main函数中,我怀疑它是否真的有效。

那我怎么能停止服务器?

非常感谢!

3 个答案:

答案 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);}
    });

}

希望它有所帮助。