被废弃的dispatch_get_current_queue

想说说被废弃的dispatch_get_current_queue,不得不提一个概念:可重入。

什么是可重入,来自维基百科:若一个程序或子程序可以“安全的被并行执行(Parallel computing)”,则称其为可重入(reentrant或re-entrant)的。

即当该子程序正在运行时,可以再次进入并执行它(并行执行时,个别的执行结果,都符合设计时的预期)。

若一个函数是可重入的,则该函数:

不能含有静态(全局)非常量数据

不能返回静态(全局)非常量数据的地址

只能处理由调用者提供的数据

不能依赖于单实例模式资源的锁

不能调用(call)不可重入的函数(有呼叫(call)到的函数需满足前述条件)

有时候我们很希望知道当前执行的queue是谁,比如UI操作需要放在main queue中执行。如果可以知道当前工作的queue是谁,就可以很方便的指定一段代码操作在特定的queue中执行。 dispatch_get_current_queue() 正好能帮上忙。于是乎,在指定的queue中做一些操作,就可以非常清晰的实现:

void func(dispatch_queue_t queue, dispatch_block_t block)
{
    if (dispatch_get_current_queue() == queue) {
        block();
    }else{
        dispatch_sync(queue, block);
    }
}

然后潜意识里,觉得这个函数是可重入的。

但当target queue恰好是current queue时,同步阻塞会导致死锁。

- (void)deadLockFunc
{
    dispatch_queue_t queueA = dispatch_queue_create("com.yiyaaixuexi.queueA", NULL);
    dispatch_queue_t queueB = dispatch_queue_create("com.yiyaaixuexi.queueB", NULL);
    dispatch_sync(queueA, ^{
        dispatch_sync(queueB, ^{
            dispatch_block_t block = ^{
                //do something
            };
            func(queueA, block);
        });
    });
}

问题出在GCD队列本身是不可重入的,串行同步队列的层级关系,是出现问题的根本原因。

更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/project/

为了防止类似的误用,苹果在iOS6废弃了dispatch_get_current_queue()方法。强大的dispatch_get_current_queue()也只能当作一个调试工具了。

那么应该如何保证GCD方法可重入呢?

dispatch_queue_set_specific 标记队列

递归锁

分别给出两种方法的示例代码片段:

1)dispatch_queue_set_specific

dispatch_queue_t queueA = dispatch_queue_create("com.yiyaaixuexi.queueA", NULL);
   dispatch_queue_t queueB = dispatch_queue_create("com.yiyaaixuexi.queueB", NULL);
   dispatch_set_target_queue(queueB, queueA);    

   static int specificKey;
   CFStringRef specificValue = CFSTR("queueA");
   dispatch_queue_set_specific(queueA,
                               &specificKey,
                               (void*)specificValue,
                               (dispatch_function_t)CFRelease);    

   dispatch_sync(queueB, ^{
       dispatch_block_t block = ^{
               //do something
       };
       CFStringRef retrievedValue = dispatch_get_specific(&specificKey);
       if (retrievedValue) {
           block();
       } else {
           dispatch_sync(queueA, block);
       }
   });

2)递归锁

void dispatch_reentrant(void (^block)())
{
    static NSRecursiveLock *lock = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        lock = [[NSRecursiveLock alloc]init];
    });
    [lock lock];
    block();
    [lock unlock];
}    

    dispatch_queue_t queueA = dispatch_queue_create("com.yiyaaixuexi.queueA", NULL);
    dispatch_block_t block = ^{
         //do something
    };
    dispatch_sync(queueA, ^{
        dispatch_reentrant(block);
    });

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索函数
, 个别程序不能调试
, dispatch_sync
, block
, dispatch
, queue
, 可重入
, 废弃函数
, queue()
废弃
dispatchgetmainqueue、dispatch queue t、dispatch queue、ios dispatch queue t、dispatch main queue,以便于您获取更多的相关知识。

时间: 2024-11-02 12:51:39

被废弃的dispatch_get_current_queue的相关文章

清理废弃资源-资源清理~~~ 安卓废弃资源清理

问题描述 资源清理--- 安卓废弃资源清理 安卓废弃资源清理,不用图片,废弃方法,废弃类等等,在Android studio中安全删除 解决方案 http://www.waychel.com/shi-yong-android-studiode-lintqing-chu-wu-yong-de-zi-yuan-wen-jian/

HTML中的一些废弃元素

如果我们在进行CSS网页布局的时候,还在使用被W3C废弃的元素,那就失去了使用CSS的意义,虽然它们可能同样被样式控制. 如果我们在进行CSS网页布局的时候,还在使用被W3C废弃的元素,那就失去了使用CSS的意义,虽然它们可能同样被样式控制. 在XHTML中不再使用HTML中的一些废弃元素.它们主要有以下一些. Elements and attributes that have been deprecated in the most recent version of XHTML, XHTML 

PHP 5.3与5.5废弃/过期函数整理

  做PHP的相信都知道,从PHP5.3开始加入了一个新的报错级别DEPRECATED,即将废弃/过期.我们一个个版本来过. 在php5.3被放弃的函数有:  代码如下   call_user_method() (使用 call_user_func() 替代) call_user_method_array() (使用 call_user_func_array() 替代) define_syslog_variables() dl() ereg() (使用 preg_match() 替代) ereg

Win8系统删除主题删除废弃残留下来的主题

  很多用户喜欢给Win8安装主题,但经常一个主题只使用一段时间,时间久了很多废弃主题就残留下来了.那么Win8系统如何删除主题呢? 方法一:"个性化"窗口中删除 桌面上右键 – 个性化,打开"个性化"窗口,要使你想要删除的主题处于未被使用的状态,如果还在使用,那么就点击其他的主题更换成其他主题.然后在想要删除的主题上点击右键,就会显示"删除主题"选项,点击即可删除该主题. 注:此方法只对"我的主题"有效.删除"Wi

这些废弃的 HTML 标签不要用

HTML 已经发展了多年,现在 W3C 已经发布了 HTML 5.1 的提案推荐标准,一些陈旧废弃的标签已经在后继的标准中逐渐消失.这里为大家列出那些已经被废弃 HTML 标签,看看你是不是还在使用它们. <acronym> 首字母缩写,例如 WWW 类似的有<abbr>标签,表示单词缩写,例如 <abbr>inc.</abbr>.语法如下: <acronym title="World Wide Web">WWW</ac

利用废弃建筑建设数据中心

一些建筑往往因为各种原因废弃或重新得到回收改造,日前,在芬兰一个地下飞机工厂被改建成为一个数据中心. 最令人印象深刻的回收建筑是建在2000多年前的埃及丹达腊哈索尔神庙,比一般的寺庙要早2000年.而当它成为一个基督教教堂,其女神哈托尔的形象转变成圣母玛利亚.   这并不是被变成一个数据中心,尽管至少不是那么久远.但据所知至少有三个数据中心建在废弃的教堂中. 波士顿学院圣埃德蒙大厅的数据中心就建在一个天主教的教堂中,有彩色玻璃的地方.在英国利兹,AQL公司把数据中心建在废弃的塞勒姆教堂内.而西班

iOS9中关于地址簿ABAddressBookXXX之类方法被废弃的解决

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 在iOS9的SDK中我们会发现原来地址簿权限查询,获取以及创建之类的方法都被标记为废弃: 虽然仍然可以使用,但是谁也不愿意看到一大堆警告在眼前闪来闪去的的. 下面给出替换方法. 原来的API大家可以注意到都是以C函数给出的,Apple可能觉得这不怎么漂亮,所以他们重新设计了一个CNContactStore类来使其符合Objc类似的赶脚-你可以认为该类对应着iO

网传河南大桥桥基靠木头支撑 系日本所建早废弃

由木桩支撑的桥墩 网络资料图片 当地官方:该桥抗战时期由日本人采用旧时工艺建造,已弃用33年 据大河报报道,一架高高的混凝土大桥,河床上的桩基却是用木头支撑.昨日下午,这则附带图片的微博一经发布,就引发众多网友围观,很多人指责建桥方偷工减料.对此,当地官方经核实后回应称,该桥系抗战时期由日本人建造,目前已废弃33年,木桩支撑桥墩应是旧时施工工艺. 1木头支撑的大桥引发网友吐槽 昨日中午12时23分,网友"@自由人重生" 首发该微博说,"河南罗山县有一座公路桥,现在河流干涸了,

设计师利用废弃印刷电路板制成创意马桶

[EP环保网报道]据国外媒体报道,电子科技让给我们的生活带来了翻天覆地的变化,而电子垃圾对地球环境的危害也日益突出.随着环保意识的增强,人们尽可能低的减少这些高科技电子产品带来的废品污染问题等,设计师Steven Rodrig就致力于将这些废弃的印刷电路板制作成各种生活用品,例如这款这款有创意的马桶.Steven Rodrig的目标是把每块废弃的电路板都雕塑成有机的生命体,并将他的雕塑作品称作"PCB混合媒介"(Printed circuit boards,印刷电路板), 它们全部都由