【问题标题】:App blocks while dipatching a queue调度队列时应用程序阻塞
【发布时间】:2023-03-06 08:52:02
【问题描述】:

我正在使用 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];
    }
}

[编辑] 它不一致地阻塞,并非总是如此,因为应用程序没有做任何事情我暂停它,我看到线程已经停止在那里,它永远不会继续执行。 怎么了?有什么想法吗?

谢谢

【问题讨论】:

  • 尝试启用僵尸对象:stackoverflow.com/questions/5386160/…
  • 你怎么知道它在那里崩溃了?
  • 显示确切的错误/崩溃消息和回溯。
  • 依赖于ivars的函数应该使用断言,你试过NSParameterAssert(moduleQueue);吗?
  • 好吧,它不会真的崩溃,对不起,我会编辑我的帖子...

标签: objective-c grand-central-dispatch xmppframework


【解决方案1】:

块有时需要保留变量以确保它们在执行时可用。如果在块内使用局部变量,则应在块外声明时将其初始化为零。

【讨论】:

  • 块不会隐式保留使用__block 声明的变量的值。此外,如果提问者使用 ARC,则该变量已隐式初始化为 nil。
【解决方案2】:

您解释的行为与您在主线程上尝试通过 GCD 在主线程上执行操作时出现的行为完全匹配。所以你应该检查 moduleQueue 是否是主队列,然后就是这样。尝试检查它是否是主队列,如果是,则跳过 dispatch_sync 块。

【讨论】:

  • 好吧,即使 moduleQueue 不是主队列,如果代码是从主线程调用的,应用程序也会冻结,直到后台线程上的工作完成。这可能是一个死锁,其中另一个线程正在模块队列上运行的块内同步到主线程/队列。
  • 如果当前队列是方法将分派到的队列,则代码已经不调用dispatch_sync。更有可能的是,moduleQueue 不是主队列(或者它是,但呼叫是从其他队列进行的);队列真的很忙,或者被其他事情阻塞了。
猜你喜欢
  • 2018-06-26
  • 2014-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-12
  • 2017-09-13
  • 2011-03-27
相关资源
最近更新 更多