0

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

@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 次并看到块运行,但是当我点击第十一次时,程序会挂起。

如果我将串行队列更改为并发队列,则没有问题。我可以根据需要向队列分派任意数量的块。

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

4

2 回答 2

0

在回答关于最大块的问题时,我知道对可以排队的内容没有实际限制(可用内存除外)。当然,您应该能够排十多个队列而不会发生事故。

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

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

于 2013-08-28T06:24:43.140 回答
0

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

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

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

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

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

于 2013-09-01T18:57:04.950 回答