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也就很快執行完畢了,基本上不會造成什么延遲。
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也就很快執行完畢了,基本上不會造成什么延遲。
總結
- 上一篇: java方向好看的书
- 下一篇: 消息队列(2):常见的消息队列协议