【问题标题】:What property should I use for a Dispatch Queue after ARC?在 ARC 之后,我应该为调度队列使用什么属性?
【发布时间】:2023-03-28 03:23:02
【问题描述】:

我维护一个调度队列作为我的视图控制器的一个属性。我在视图控制器的 init 方法中创建了一次这个队列,并为一些后台任务重用了几次。在 ARC 之前,我是这样做的:

@property (nonatomic, assign) dispatch_queue_t filterMainQueue;

在初始化中:

if (filterMainQueue == nil) {
     filterMainQueue = dispatch_queue_create("com.myQueue.CJFilterMainQueue", NULL);
}

但是在 ARC 之后,我不确定这是否应该仍然是“分配”,或者应该是“强”还是“弱”。 ARC 转换器脚本没有改变任何东西,但我不确定是否有一个微妙的错误来自这个队列在使用时可能被释放的事实?

在使用 ARC 时,这 3 种类型的属性有什么区别,哪一种最适合调度队列?

【问题讨论】:

    标签: objective-c automatic-ref-counting grand-central-dispatch


    【解决方案1】:

    更新答案:

    在当前的 OS X 和 iOS 中,Dispatch 对象现在被 ARC 视为 Obj-C 对象。它们将以与 Obj-C 对象相同的方式进行内存管理,您应该为您的属性使用 strong

    这由OS_OBJECT_USE_OBJC 宏控制,在<os/object.h> 中定义。当您的部署目标是 OS X 10.8 或更高版本,或者 iOS 6.0 或更高版本时,默认设置为 1。如果您要部署到较旧的操作系统,则将其留在0,您应该在下面看到我的原始答案。


    原答案:

    Dispatch 对象(包括队列)不是 Obj-C 对象,因此唯一可能的选择是assign。如果您尝试使用strongweak,编译器将抛出错误。 ARC 对 GCD 没有影响。

    【讨论】:

    • 这在 Mountain Lion 中不再适用 - 请参阅 /usr/include/os/object.h。 GCD 和 XPC“对象”(任何你可能明确发布的东西)现在的行为与 ObjC 对象非常相似,它们可以参与 ARC。
    • @jkh 是否也包括 iOS 平台?
    • @Ankur:从 iOS 6.0 开始,是的。
    • 最好不要检查支持是否存在,而是检查它是否正在使用。改为检查OS_OBJECT_USE_OBJC
    【解决方案2】:

    以下是如何为 iOS 6.0 及以上和 iOS 6.0 以下定义 dispatch_queue_t 属性

    #if OS_OBJECT_HAVE_OBJC_SUPPORT == 1
    @property (nonatomic, strong) dispatch_queue_t serialDispatchQueue;
    #else
    @property (nonatomic, assign) dispatch_queue_t serialDispatchQueue;
    #endif
    

    对于 iOS 6.0 及更高版本,基本上 OS_OBJECT_HAVE_OBJC_SUPPORT 定义为 1。 (MAC 10.8 及更高版本)。在 iOS 6 以下定义为 0。

    OS_OBJECT_HAVE_OBJC_SUPPORT 定义了像 GCD 这样的 OS 对象有客观的 C 支持。因此 ARC、内存管理、引用计数等适用于 GCD 对象。

    【讨论】:

    【解决方案3】:

    这是我使用的:

    @property (readwrite, strong, nonatomic) __attribute__((NSObject)) dispatch_queue_t queue;
    

    【讨论】:

    • 它基本上将一个非 ObjC 对象转换为一个 ObjC 属性,因此您可以像 self.queue 一样轻松使用它
    • @Arvin 6.1 发生了一些变化,影响了这一点。它抱怨 attribute 并删除它现在似乎有效。我没有遇到任何问题,所以我猜测属性(读写、强、非原子)dispatch_queue_t 队列是安全的吗?
    • 我同意……Apple 的那些疯狂的人。他们接下来会做什么? ;-)
    【解决方案4】:

    基于iOS7,我测试了dispatch_queue对象是否是objective-c对象,我发现它们已经是objective-c对象。解释这一点,attribute((NSObject)) 现在没有必要了。

    【讨论】:

      【解决方案5】:

      TL;DR:dispatch_queue_t 现在是一个 Objective C 对象,可以使用 ARC 进行管理。

      我还没有测试到这有多远,但是使用 iOS 7 SDK 和 Xcode 5,dispatch_queue_t 是一个对象类型。我将队列的属性声明为

      @property (nonatomic, strong) dispatch_queue_t syncQueue;
      

      编译器很高兴,一切都按预期工作。我明确知道这在 iOS 4 或 5 中是行不通的(在 ARC 之前,它是 retain 而不是 strong)。我深入研究了dispatch_queue_t 的定义,发现了这个:

      /*!
       * @typedef dispatch_queue_t
       *
       * @abstract
       * Dispatch queues invoke blocks submitted to them serially in FIFO order. A
       * queue will only invoke one block at a time, but independent queues may each
       * invoke their blocks concurrently with respect to each other.
       *
       * @discussion
       * Dispatch queues are lightweight objects to which blocks may be submitted.
       * The system manages a pool of threads which process dispatch queues and
       * invoke blocks submitted to them.
       *
       * Conceptually a dispatch queue may have its own thread of execution, and
       * interaction between queues is highly asynchronous.
       *
       * Dispatch queues are reference counted via calls to dispatch_retain() and
       * dispatch_release(). Pending blocks submitted to a queue also hold a
       * reference to the queue until they have finished. Once all references to a
       * queue have been released, the queue will be deallocated by the system.
       */
      DISPATCH_DECL(dispatch_queue);
      

      听上去,它应该不起作用,所以我检查了DISPATCH_DECL 的定义,发现了这个,它解释了一切:

      /*
       * 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.
       */
      

      【讨论】:

        猜你喜欢
        • 2012-11-11
        • 1970-01-01
        • 1970-01-01
        • 2020-09-06
        • 1970-01-01
        • 2012-01-26
        • 2018-06-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多