释放 GCD 调度队列属性的正确方法是什么?

发布于 2024-10-30 04:30:28 字数 398 浏览 0 评论 0原文

我正在使用一个dispatch_queue,它是通过其所有者的属性访问的,如下所示:

@property (nonatomic, assign) dispatch_queue_t queue;

注意assign关键字。队列在对象的整个生命周期中使用,因此由对象拥有。当拥有的对象被释放时,我释放队列:

-(void)dealloc
{
    dispatch_release(self.queue);
    self.queue = nil;
}

如何正确释放它?使用 retain/release 有效吗?

如果在调用释放时队列中有待处理/正在运行的内容,会发生什么情况?

I'm using a dispatch_queue which is accessed through a property of its owner, like this:

@property (nonatomic, assign) dispatch_queue_t queue;

Note the assign keyword. The queue is used throughout the objects life and thus owned by the object. I release the queue when the owning object is deallocated:

-(void)dealloc
{
    dispatch_release(self.queue);
    self.queue = nil;
}

How do I properly release this? Would using retain/release work?

What happens if there is stuff pending/running on the queue while calling release?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

左岸枫 2024-11-06 04:30:28

以下内容是从开发者文档中窃取的:

调度队列和其他调度
对象是引用计数数据
类型。当您创建连续剧时
调度队列,它有一个初始的
引用计数为 1。您可以使用
调度保留和调度释放
递增和递减函数
根据需要引用计数。什么时候
队列的引用计数达到
零,系统异步
释放队列。

当您的应用程序不再需要
调度队列,它应该释放
它与dispatch_release函数一起使用。
任何提交给a的待处理块
队列保存对该队列的引用,
所以队列不会被释放,直到
所有挂起的区块均已完成。

注意:您不需要保留或
释放任何全局调度
队列,包括并发
调度队列或主调度
队列。任何试图保留或
释放队列将被忽略。

因此,在任何要使用 -retain 的地方都使用dispatch_retain,在任何要使用 -release 的地方都使用dispatch_release。

调度队列遵循与 Objective-C 对象相同的通用内存管理约定。并且在所有排队的块完成之前它们不会被释放。

如果您确实想要一种方法来关闭调度队列:无法通过任何类型的 API 取消所有排队的块,因此它们始终必须运行完成。加快此过程的一种方法是在管理调度队列的类中使用 BOOL 变量:_isValid。当你想关闭队列时,可以将_isValid设置为NO。提交到队列的所有块在执行任何工作之前都应首先检查 _isValid。

旁注:使用 NSOperationQueue 可能更合适。请参阅 Chris Hanson 的博客文章

The following is stolen from the developer documentation:

Dispatch queues and other dispatch
objects are reference-counted data
types. When you create a serial
dispatch queue, it has an initial
reference count of 1. You can use the
dispatch_retain and dispatch_release
functions to increment and decrement
that reference count as needed. When
the reference count of a queue reaches
zero, the system asynchronously
deallocates the queue.

When your application no longer needs
the dispatch queue, it should release
it with the dispatch_release function.
Any pending blocks submitted to a
queue hold a reference to that queue,
so the queue is not deallocated until
all pending blocks have completed.

Note: You do not need to retain or
release any of the global dispatch
queues, including the concurrent
dispatch queues or the main dispatch
queue. Any attempts to retain or
release the queues are ignored.

So anywhere you would use -retain use dispatch_retain and anywhere you would use -release use dispatch_release.

Dispatch queues follow the same general memory management conventions as objective-c objects. And they won't be dealloc'ed until all blocks queued are finished.

If you do want a way to shut down a dispatch queue: There's no way to cancel all enqueued blocks via any sort of API, so they always must run to completion. One way to expedite this process is to have a BOOL variable in the class managing the dispatch queue: _isValid. When you want to shut down the queue, you can set _isValid to NO. All blocks submitted to the queue should first check _isValid before doing any work.

A side comment: It may be more appropriate to use NSOperationQueue. See Chris Hanson's blog post.

喜爱皱眉﹌ 2024-11-06 04:30:28

一件有趣的事情是,如果提交到队列的块引用拥有该队列的对象(例如“self”),则该对象将不会命中 dealloc,直到队列中的所有待处理块都完成反正。

这是一个演示这一点的项目:

https://github.com/joshrl/GDCQueueDeallocTest

One interesting thing about this is that if the blocks submitted to the queue reference the object that owns the queue (e.g. "self"), the object will not hit dealloc until all pending blocks in the queue are completed anyway.

Here is a project that demonstrates this:

https://github.com/joshrl/GDCQueueDeallocTest

虫児飞 2024-11-06 04:30:28

如果有东西会发生什么
正在队列中等待/运行
调用释放?

这是安全的。挂起/运行队列从系统中保留。调用dispatch_release只会影响队列的保留计数。请参阅dispatch_async 等手册页。

What happens if there is stuff
pending/running on the queue while
calling release?

It is safe. pending/running queue is retained from system. Calling dispatch_release just affects the retain count of the queue. See man page of dispatch_async or so forth.

唱一曲作罢 2024-11-06 04:30:28

像这样设置你的属性:

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

Assign 是隐含的,Strong 将保留队列,告诉 ARC 将其视为 NSObject。

setup your property like so:

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

Assign is implied and Strong will retain the queue telling ARC to treat it as an NSObject.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文