在dispatch_queue_t上检查相等性

4
如何检查dispatch_queue_t变量之间的相等性?
dispatch_queue_t currentQueue = dispatch_get_current_queue();
dispatch_queue_t mainQueue = dispatch_get_main_queue();
if (currentQueue == mainQueue) {

}

来自文档:

typedef struct dispatch_queue_s *dispatch_queue_t;

我不确定,但这是否意味着它是指向dispatch_queue_s结构体的指针?

由于我无法检查指针的相等性,我不确定如何检查一个dispatch_queue_t是否和另一个相同?

3个回答

24

由于 dispatch_get_current_queue() 已被弃用,我们可以通过比较当前队列和您的队列的标签(或像@jkh建议的特定信息)来进行替代。

对于标签使用:

dispatch_queue_get_label(dispatch_queue_t queue);

并传递 DISPATCH_CURRENT_QUEUE_LABEL 以获取当前队列的标签。

具体而言:

dispatch_queue_get_specific(dispatch_queue_t queue, const void *key);

获取您的特定队列并

dispatch_get_specific(const void *key);

为了创建队列,需要设置标签和/或具体队列。

例如,当您创建它时。

dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);

或者使用特定属性的setter函数

dispatch_queue_set_specific(dispatch_queue_t queue, const void *key,
    void *context, dispatch_function_t destructor);

这非常有帮助。我在创建队列时使用了dispatch_queue_set_specific和一个简单的布尔标志,而用dispatch_get_specific来查看该标志是否已设置。效果非常好。 - pottedmeat
使用标签或特定变量存储数据有优劣之分吗? - Alfie Hanssen
@AlfieHanssen 不确定是否有100%的差异,但认为性能差异不大,可以使用更方便的选项。 - alexey.metelkin
有趣。我不知道 DISPATCH_CURRENT_QUEUE_LABEL,文档中没有提到它。事实上,文档说 queue 不能为 NULL,但头文件却说 DISPATCH_CURRENT_QUEUE_LABELqueue 的有效参数,并将其定义为 NULL... - skagedal

2
这取决于您所在的队列。在这种特殊情况下,请使用以下内容:
if ([NSThread isMainThread]) {}

一般情况下,您可以使用dispatch_get_current_queue()来测试您所在的队列。在这种情况下,您可以使用==运算符来进行测试。引用苹果并发编程指南中的Dispatch Queues页面:

使用dispatch_get_current_queue函数进行调试或测试当前队列的标识。从块对象内部调用此函数将返回该块提交的队列(现在可能正在该队列上运行)。从块外部调用此函数将返回应用程序的默认并发队列。


那个引用确实说你可以使用 dispatch_get_current_queue “来测试当前队列的身份”。但问题在于它只能在分派块内按预期工作。 - Peter Hosey

2

回答的第一部分:你想做什么?为什么需要比较队列?如果你只需要使用某些特定元数据“标记”队列,请考虑使用dispatch_queue_{set, get}_specific()。

回答的第二部分:不要对dispatch_get_current_queue()进行任何操作。它仅用于调试目的,一直被不鼓励使用。


1
这是否是为什么dispatch_get_current_queue()在iOS 6.0标头中被标记为弃用(尽管在Mountain Lion中没有)的原因?我一直在使用它来运行一个包装函数,在串行队列上同步运行一个块,但如果该函数恰好从该队列本身中调用,则不会出现死锁。我曾经认为我们可以使用它来检查调用函数的调度队列的身份。我想这不是安全的做法? - Brad Larson
通常而言,这不是一种安全的做法,因为队列A可能会对队列B进行同步调度,然后队列B会尝试再次调度回队列A,但这种方法无法检测到死锁。 - dgatwood

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接