GCD和NSOperation多線程技術

 
第一講  GCD
 
GCD會管理多線程的生命週期
 
GCD底層線程池,隊列跟底層線程池之間的交互,底層線程池對線程進行了複用,使用效率要高
 
GCD跟NSThread對比
 
 
  1. 開不開線程,和執行任務的函數有關
- 同步不開
- 異步開
  1. (異步)開幾條線程,和隊列有關
- 串行隊列最多開一條
- 併發隊列開N條,具體條數由GCD決定!
 
 
主隊列:
 
主隊列同步會死鎖:
 
注意主隊列同步也能夠不死鎖,具體狀況具體對待
 
主隊列異步: 不會開啓線程,在主線程中執行,可是主隊列中的任務須要等待主線程中任務執行完畢以後才能執行
 
barrier阻塞:
會先循環執行完下載完成(全部異步執行完以後再執行barrier的block中代碼),同一線程中順序執行
注意:dispatch_barrier_async 必須使用自定義隊列,不然執行效果和全局隊列一致
 
dispatch_once 只執行一次的代碼,注意單例中的static可以保證在block中局部變量能夠記錄保存在靜態區,不會被銷燬
 
dispatch_once是同步的,是線程安全的, dispatch_once內部也有一把鎖,這把鎖的性能很高
 
 
dispatch_group  調度組  dispatch_group_notify 異步的
 
 
dispatch_after 延遲操做- 異步執行的   所以在dispatch_after的block中執行的任務是在子線程中執行
 
 
第二講  NSOperation
 
iOS8以後,GCD底層的線程池特別慷慨,只要要就給,能夠開不少條線程
 
NSOperation是iOS2.0推出的,GCD是iOS4.0推出的
ARC是Xcode4.2推出的
 
 
NSInvocationOperation和NSBlockOperation的使用(都是異步併發執行的)
 
 
線程間通信:
 
NSOperation和GCD的對比:
 
NSOperation設置最大併發數  setMaxConcurrentOperationCount
 
暫停繼續(隊列的掛起狀態),掛起的是隊列,不會影響正在執行的操做
 
 
 
取消,暫停和繼續
 
依賴關係
 
異步下載圖片
在異步下載圖片的時候的問題及解決:
 
 
當異步下載圖片以後,因爲blockOperation是異步下載的,當返回cell的時候image還未下載下來,因此因爲cell的imageView懶加載,並未顯示圖片,當點擊或者上下滾動才顯示
 
解決辦法:佔位圖片提早設置imageView,固定imageView的大小
 
可是此時又有問題,佔位圖片太大,下載圖片小,因此一開始顯示佔位圖片大點擊cell以後顯示小的下載圖片
 
解決辦法:自定義cell,設置好imageView的大小,能夠完整顯示佔位圖片和下載圖片
 
然而還有問題,此時圖片每次滾動都會下載,而且當網速不一樣會致使圖片錯位,緣由:好比第一個cell的圖片下載很快,第九個以後就很慢,當第一個cell進入緩存池以後,第十個cell會進行cell複用,此時cell的圖片下載很慢,圖片還未下載完,當在往上滾動的時候,第一個cell會複用第十個 cell,因爲第一個cell圖片下載快,因此顯示以後過幾秒會再下載顯示第十個cell未下載完的圖片,從而發生圖片錯位的現象。
 
解決辦法:利用MVC模式,在模型中定義圖片屬性,將圖像異步保存在模型中,並刷新當前行調用數據源方法,在cell中判斷模型是否有圖片,顯示模型中存儲的圖像。這樣同時解決了不斷從網絡下載的問題
 
操做緩衝池:
 
爲何須要操做緩衝池?由於在下載網絡圖片的時候,當網絡很慢,而用戶快速滑動,好比第一個cell的圖片沒有下載完,因而會在建立一個操做添加到隊列中,這樣會形成資源的浪費
 
 
下載結束,清除操做緩衝
 
圖像緩衝池的引入
 
因爲模型內保存圖片跟模型綁定的很緊,當接收到內存警告的時候很差釋放,因此須要引入圖像緩衝池,相似於操做緩衝池,用url做爲key用字典緩衝
 
layoutsubviews方法的調用
 
 
內存警告清理緩衝池
 
實現沙盒緩存見SDWebImage
相關文章
相關標籤/搜索