GCD简介五:补充

1.GCD在iOS4.0及以上可用。

2.GCD中,主线程队列是串行的;全局队列是并行的,并由整个进程共享;用户自建队列,在iOS4.3以下,只能是串行,iOS4.3及以上,可以是并行的。

3.dispatch_suspend挂起队列,dispatch_resume恢复队列。队列有暂停计数,当计数为0时,队列的执行被暂停,但是当前正在执行的block不会被暂停。

4.自己创建的队列,要自己释放,用dispatch_release()方法。
   GCD不支持ARC。

5.如果挂起一个队列或者source,那么在销毁它之前,必须对其进行恢复。

6.全局队列和主线程队列不响应某些修改动作,比如:suspend,resume,dispatch_set_context,release,retain等动作。因为这些队列不是用户创建的。

7.GCD用户自建队列,添加到队列中的等待中的block会使队列引用计数加1,所以在等待中的block执行完毕前,队列不会销毁,即使调用了dispatch_release方法。

6.当在一个视图控制器中使用了GCD,并有回调主线程执行代码(在主线程中使用self关键字访问了界面控件,或者使用了成员变量)。如果在block执行之前,视图控制器从视图中移除并调用了release,此时控制器在内存中还存在,并没有被销毁。在block执行了之后,视图控制器才真正销毁掉。也就是说,在使用block时,GCD retain了视图控制器(由于拷贝block引起的retain)。

7.第6条中说的问题会引起控制器销毁延迟,但是不会出现不能释放的问题。其实如果视图不被retain,当回调执行时,会发生空指针异常。其实对于这个销毁延迟的问题,不用做特别的处理,是有道理的,原因如下:
(1)GCD不提供从队列中移除block的方法,即在视图销毁前,没有办法控制block的执行。
(2)在GCD自建队列中的block执行完之前,队列不会被真正销毁,即使调用了dispatch_release方法。
(3)综合以上两点,并对比代理模式,delegate使用assign,使代理不被retain,当代理被销毁了以后,如果还调用代理的方法,也会发生空指针异常,但是我们有办法处理:在代理控制器销毁之前,将代理变量设置我nil,这样代理方法就不会被调用了。但是对于GCD,我们没有类似的权限来控制block。

8.针对第7条中问题的block代码优化:
(1)原理:虽然我们不能在控制器销毁之前移除block,但是我们可以控制block时执行的代码。
(2)设置一个Bool变量,比如isControllerWantToRelease,初始化为NO,当我们在控制器外部将控制器移除并调用release代码之前,通知控制器将要移除控制器,控制器收到消息后,将isControllerWantToRelease设置为YES。
(3)在Block代码内部,首先判断isControllerWantToRelease状态,如果为NO,则执行真正的功能代码;如果为YES,则不执行任何代码。
(4)这样的话,GCD在执行block时,就不会花费任何时间,包括队列中现存的关于此控制器的所有block都会很快执行完。因此,当控制器的release方法调用之后,block也就很快执行完毕了,基本上不会造成什么延迟。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值