调度队列时应用程序阻塞
Posted
技术标签:
【中文标题】调度队列时应用程序阻塞【英文标题】:App blocks while dipatching a queue 【发布时间】:2012-04-25 12:30:35 【问题描述】:我正在使用 XMPPFramework,在它的代码中有这样的方法:
- (NSDictionary *)occupants
if (dispatch_get_current_queue() == moduleQueue)
return occupants;
else
__block NSDictionary *result;
dispatch_sync(moduleQueue, ^//IT BLOCKS HERE, WITHOUT MESSAGE
result = [occupants copy];
);
return [result autorelease];
[编辑] 它不一致地阻塞,并非总是如此,因为应用程序没有做任何事情我暂停它,我看到线程已经停止在那里,它永远不会继续执行。 怎么了?有什么想法吗?
谢谢
【问题讨论】:
尝试启用僵尸对象:***.com/questions/5386160/… 你怎么知道它在那里崩溃了? 显示确切的错误/崩溃消息和回溯。 依赖于ivars的函数应该使用断言,你试过NSParameterAssert(moduleQueue);
吗?
好吧,它不会真的崩溃,对不起,我会编辑我的帖子...
【参考方案1】:
您解释的行为与您在主线程上尝试通过 GCD 在主线程上执行操作时出现的行为完全匹配。所以你应该检查 moduleQueue 是否是主队列,然后就是这样。尝试检查它是否是主队列,如果是,则跳过 dispatch_sync 块。
【讨论】:
好吧,即使 moduleQueue 不是主队列,如果代码是从主线程调用的,应用程序也会冻结,直到后台线程上的工作完成。这可能是一个死锁,其中另一个线程正在模块队列上运行的块内同步到主线程/队列。 如果当前队列是方法将分派到的队列,则代码已经不调用dispatch_sync
。更有可能的是,moduleQueue
不是主队列(或者它是,但呼叫是从其他队列进行的);队列真的很忙,或者被其他事情阻塞了。【参考方案2】:
块有时需要保留变量以确保它们在执行时可用。如果在块内使用局部变量,则应在块外声明时将其初始化为零。
【讨论】:
块不会隐式保留使用__block
声明的变量的值。此外,如果提问者使用 ARC,则该变量已隐式初始化为 nil
。以上是关于调度队列时应用程序阻塞的主要内容,如果未能解决你的问题,请参考以下文章