【问题标题】:Why is ARC complaining about dispatch_queue_create and dispatch_release in iOS 6?为什么 ARC 抱怨 iOS 6 中的 dispatch_queue_create 和 dispatch_release?
【发布时间】:2012-11-22 01:36:23
【问题描述】:

我声明了一个引用 GCD 队列的属性:

@property (assign) dispatch_queue_t backgroundQueue;

在一个类的 init 方法中,我创建了一个串行队列:

backgroundQueue = dispatch_queue_create("com.company.app", DISPATCH_QUEUE_SERIAL);

ARC 报错:“将保留对象分配给 unsafe_unretained 变量;分配后对象将被释放”

我必须使用 __bridge_transfer 吗?

在 -dealloc 中我正在释放队列:

dispatch_release(backgroundQueue);

ARC 再次抱怨:“ARC 禁止发送明确的 'release' 消息”

我觉得这很令人困惑,因为这是一个 C 函数调用,并且认为队列是 C 对象,我必须自己负责内存管理! ARC 从什么时候开始为我处理 C 对象?

【问题讨论】:

    标签: ios memory-management automatic-ref-counting grand-central-dispatch


    【解决方案1】:

    如果您使用的是 iOS 6 SDK,则会出现此错误消息。

    iOS 6.0 SDKMac OS X 10.8 SDK中,每个dispatch对象也是objective C的一部分。所以你不用担心内存,ARC会管理dispatch_queue的内存。

    详情请咨询link

    【讨论】:

    • 所以基本上,我不需要为 dispatch_queue 设置属性。我需要做的就是在代码中的任何地方使用它。我这样说对吗?
    • 我的意思是你不想在 iOS 6 中调用 dispatch_retain 和 dispatch_release。ARC 会管理内存
    • 这个怎么样:ARC 抱怨:“将保留对象分配给 unsafe_unretained 变量;分配后对象将被释放”?
    • 永远不要将保留对象分配给 unsafe_unretained 对象。这是所有对象的正常情况,不仅是调度对象
    • 那么解决该部分的方法是删除属性声明中的分配?
    【解决方案2】:

    在 iOS 6 中,您可以 cmd+单击 dispatch_queue_t 并查看:

    /*
     * By default, dispatch objects are declared as Objective-C types when building
     * with an Objective-C compiler. This allows them to participate in ARC, in RR
     * management by the Blocks runtime and in leaks checking by the static
     * analyzer, and enables them to be added to Cocoa collections.
     * See <os/object.h> for details.
     */
    

    所以只需在属性中使用 strong 即可(除非队列在其他地方被引用并且您确实需要弱引用)。

    在 iOS 6 之前,您必须自己使用 dispatch_retain 和 dispatch_release 进行内存管理。在 iOS 6 中这样做会引发编译器错误。

    【讨论】:

    • 所以……我在 iOS 5 中 100% 正确的代码……现在内存管理不正确?惊人的!另外:很棒的编译器消息(叹气)。
    • 问个问题,RR是什么意思?
    • @Ricardo 保留释放。在 Apple 文档中,他们使用术语 MRR 来指代手动保留释放。
    • @Jano 谢谢。我知道 MRC(手动引用计数,ARC 的对应物),但从未听说过 RR。
    【解决方案3】:

    您不应该坚持使用assign。您可以使用:

    @property (nonatomic) dispatch_queue_t backgroundQueue;
    

    甚至

    @property dispatch_queue_t backgroundQueue;
    

    没有警告。

    【讨论】:

      【解决方案4】:

      神奇的dispatch_retaindispatch_release 函数是根据很多条件定义的。

      我的测试的底线: - 如果您为 sdk 5 部署,请使用它们,一切都很好 - 如果你为 sdk >= 6 部署,就别想它们了,把所有东西都当成对象吧

      你可以在这里看到更好的解释:https://stackoverflow.com/questions/8618632/does-arc-support-dispatch-queues?rq=1

      【讨论】:

        猜你喜欢
        • 2015-06-09
        • 2020-08-12
        • 2016-02-27
        • 1970-01-01
        • 1970-01-01
        • 2021-12-12
        • 2011-01-21
        • 1970-01-01
        • 2018-11-17
        相关资源
        最近更新 更多