您的位置:首页 > 其它

GCD简介五:补充

2017-02-10 12:03 101 查看
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也就很快执行完毕了,基本上不会造成什么延迟。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: