可以提交到GCD中的串行队列的块数是否有限制?

时间:2013-08-28 05:13:47

标签: queue grand-central-dispatch dispatch

我定义了一个使用延迟实例化返回串行调度队列的属性,如下所示:

@property (nonatomic, readonly) dispatch_queue_t queue;

- (dispatch_queue_t)queue
{
    if (!_queue) {
        _queue = dispatch_queue_create("com.example.MyQueue", NULL);
    }
    return _queue;
}

然后假设我为某个按钮定义了一个动作方法,该按钮为块添加了一个块:

- (IBAction)buttonTapped:(UIButton *)sender
{
    dispatch_async(self.queue, ^{
        printf("Do some work here.\n");
    });
}

实际方法的代码比简单的print语句更复杂,但这可以用于示例。

到目前为止一切顺利。但是,如果我构建并运行程序,我可以点击按钮10次并看到块运行,但是当我点击第11次时,程序会挂起。

如果我将串行队列更改为并发队列,则没有问题。我可以根据需要向队列中分配尽可能多的块。

知道可能会发生什么吗?可以发布到串行队列的块数是否有限制?

2 个答案:

答案 0 :(得分:0)

在回答关于max blocks的问题时,我知道对可排队的内容没有实际限制(除了可用内存)。当然,你应该能够在没有事故的情况下排队超过十个。

但是你的queue getter方法中有一个拼写错误。您正在设置_queue,但返回queue。您应该返回您设置的相同变量。看起来你必须定义两个ivars;也许你手动定义的一个和合成的?如果你有一个手动声明的实例变量,你应该消除它,并确保你的getter方法使用相同的实例变量,即为你合成的实例变量。另外,您是否在init方法中初始化此ivar?

如果修复此问题无法解决问题,那么问题可能在于您要分派到此队列的特定代码中,您应该与我们分享。那里有同步代码吗?与任何共享资源的任何交互?

答案 1 :(得分:0)

好的,我终于解决了这个问题。

首先,当我报告并发队列工作正常但串行队列没有时,我错了。两种类型的队列都失败了。当我观察到一切正常时,实际上是在使用主队列。所以,在这种情况下,确实没有任何并发​​性。

也就是说,问题是一个死锁问题,当我在辅助线程上处理时,从主线程记录信息 - 来自串行或并发队列。更糟糕的是,我的应用程序使用Lumberjack进行日志记录,这引入了额外的线程问题。为了解决这个问题,我将每次调用Lumberjack日志记录方法包装如下:

dispatch_async(dispatch_get_main_queue(), ^{
    // do logging here
});

这解决了这个问题。感谢您的评论。他们最终让我找到了解决方案。