我定义了一个使用延迟实例化返回串行调度队列的属性,如下所示:
@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次时,程序会挂起。
如果我将串行队列更改为并发队列,则没有问题。我可以根据需要向队列中分配尽可能多的块。
知道可能会发生什么吗?可以发布到串行队列的块数是否有限制?
答案 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
});
这解决了这个问题。感谢您的评论。他们最终让我找到了解决方案。