【问题标题】:Problems with GCD dispatching to main thread in Objective-C在 Objective-C 中将 GCD 分派到主线程的问题
【发布时间】:2013-09-25 15:31:25
【问题描述】:

我有这段代码:

dispatch_queue_t queue = dispatch_queue_create("Queue", NULL);
dispatch_async(queue, ^{
    //accessing the internet
    dispatch_sync(dispatch_get_main_queue(), ^{
        [myObject myFunction];
    });
});

在我的函数中:

dispatch_queue_t queue = dispatch_queue_create("anotherQueue", NULL);
dispatch_async(queue, ^{
    //long task that takes seconds
    dispatch_sync(dispatch_get_main_queue(), ^{
        //this is never executed
        NSLog(@"Got to main thread.");
        //updating the UI
    });
});

有人能解释为什么阻塞 ^{ NSLog(@"Got to main thread."); });不会被执行?

【问题讨论】:

  • 嗯,看到这个我就头疼。移动 NSLog 以替换 [myObject myFunction]。那应该完成您正在尝试做的事情。为什么要在异步队列中的主队列中调用异步队列中的主队列。头又疼了!

标签: objective-c multithreading


【解决方案1】:

你的主队列/主线程被阻塞了。

myFunction 中的dispatch_sync(dispatch_get_main_queue())... 之后放置一个NSLog()。我敢打赌它不会被打印,因为该块永远不会被执行(如你所说)。

如果是这样,在dispatch_sync 上设置一个断点,然后查看主队列/线程的堆栈跟踪。这应该会给你一个关于它为什么被阻止的线索。

【讨论】:

    【解决方案2】:

    您正在创建两个具有相同名称的队列。这些队列的变量位于不同的上下文中并不重要,队列是应用程序中的全局构造。以不同的方式命名每个队列using the reverse-DNS style

    【讨论】:

    • 既不是真的,也没有解释这种行为。队列的名称只不过是帮助调试的装饰性辅助工具。
    • @bbum - 我知道你在 obj-c 工作,但你能指出相关文档吗?我链接到的 Apple 文档确实说它有助于调试,但没有任何地方表明使用相同名称创建的两个队列不会引用相同的底层对象。
    • 也没有说他们这样做……
    • @RyanR 这将是那些将被明确记录并由 API 支持的行为之一,例如dispatch_get_queue_name()。它也会很慢,因此需要一个非常好的理由来做到这一点,并且它与它正在替换的线程 API 是陌生的(这同样需要有理由去那里)。同样,虽然这将是一个实现细节,但它很容易测试。但是,可以肯定的是,可以澄清文档;随时提交增强错误!
    • 可以确认队列不是按名称唯一的。我在我的代码中使用了许多同名的串行队列,并使用 heap(1) 验证了我的进程中 OS_dispatch_queue 对象的计数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-27
    • 1970-01-01
    • 2011-12-07
    • 1970-01-01
    • 2011-08-05
    相关资源
    最近更新 更多