暂停GCD查询问题 [英] Suspending GCD query problem

查看:56
本文介绍了暂停GCD查询问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法暂停gcd查询.这是一些演示问题的代码:

i have trouble suspending a gcd query. Here is some code that demonstrates the problem:

static dispatch_queue_t q=nil;

static void test(int a){
    if(q){
        dispatch_suspend(q);
        dispatch_release(q);
        q=nil;
    }
    q=dispatch_get_global_queue(0,0);
    dispatch_async(q,^ {
        while(1){NSLog(@"query %d",a);sleep(2);}
    });

}

int main(int argc, const char* argv[]){
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    test(1);

    //blah blah blah

    test(2);

    while(1){}
    [pool release];
    return 0;
}

我想做的是在第二次调用功能测试时挂起,释放并重新初始化查询q,但是显然我的代码是错误的,并且查询q的两个实例都可以继续运行.

What I'm trying to do is suspend,release and reinitialise query q when function test is called the second time, but apparenty my code is wrong and both instances of query q continue to run.

非常感谢您的帮助.

推荐答案

在实际调用dispatch_suspend()之前已异步异步调度到队列中的任何块都将在挂起生效之前运行.在您的代码中,您正在异步触发一堆块,因此当您调用test(2)时,某些块可能仍在队列中,这些块将被执行.

Any blocks that have been dispatched to your queue asynchronously before you actually call dispatch_suspend() will get run before the suspend takes effect. In your code you are firing off a bunch of blocks asynchronously, so some are probably still in the queue when you call test(2), and those blocks will be executed.

如果您希望能够取消正在运行的作业,则需要按照自己的逻辑进行. GCD故意没有公开真正的取消API.您可以执行以下操作:

If you want to be able to cancel your running jobs, you'll need to do so in your own logic. GCD purposefully doesn't expose a true cancellation API. You could do something like this:

@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);}
    });

}

通过这种方式,每个块都将保留对一个对象的引用,该对象知道它是否应该停止工作.

In this way, each block will keep a reference to an object that knows if it should stop doing work.

这篇关于暂停GCD查询问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆