小編在前一篇中介紹了多線程實現的五種經常使用方法。在接下來所介紹的這種方法是最具備魅力的,最具備誘惑的實現多線程的方案---GCDweb
1、什麼是GCD緩存
GCD是Grand Central Dispatch的簡稱,是基於C語言的。若是使用GCD,徹底由系統管理線程,咱們不須要編寫線程代碼。只需定義想要執行的任務,而後添加到適當的調度隊列(dispatch queue)。GCD會負責建立線程和調度你的任務,系統直接提供線程管理,大大的提升代碼的執行效率與多核的利用率。
1.GCD的一個重要概念是隊列,它的核心理念:將長期運行的任務拆分紅多個工做單元,並將這些單元添加到dispath queue中,系統會爲咱們管理這些dispath queue,爲咱們在多個線程上執行工做單元,咱們不須要直接啓動和管理後臺線程。多線程
2.系統提供了許多預約義的dispath queue,包括能夠保證始終在主線程上執行工做的dispath queue。也能夠建立本身的dispath queue,並且能夠建立任意多個。GCD的dispath queue嚴格遵循FIFO(先進先出)原則,添加到dispath queue的工做單元將始終按照加入dispath queue的順序啓動。併發
3.dispatch queue按先進先出的順序,串行或併發地執行任務異步
2、建立和管理GCDasync
併發dispatch queue能夠同時並行地執行多個任務,不過併發queue仍然按先進先出的順序來啓動任務。併發queue會在以前的任務完成以前就出列下一個任務並開始執行。併發queue同時執行的任務數量會根據應用和系統動態變化,各類因素包括:可用核數量、其它進程正在執行的工做數量、其它串行dispatch queue中優先任務的數量等.函數
1 //建立一個隊列 2 dispatch_queue_attr_t queue = dispatch_queue_create("test", NULL); 3 /********此種方式是異步多線程的運行*********/ 4 dispatch_async(queue, ^{ 5 for (int i = 0; i < 100; i++) { 6 NSLog(@"---這是多線程---%d",i); 7 } 8 9 //回到主線程 10 dispatch_sync(dispatch_get_main_queue(), ^{ 11 BOOL isMain = [NSThread isMainThread]; 12 if (isMain) { 13 NSLog(@"isMain"); 14 } 15 }); 16 }); 17 18 /********此種方式是同步多線程的運行*********/ 19 dispatch_sync(queue, ^{ 20 //demo 21 });
GCD提供了函數讓應用訪問幾個公共dispatch queue:測試
1> 使用dispatch_get_current_queue函數做爲調試用途,或者測試當前queue的標識。在block對象中調用這個函數會返回 block提交到的queue(這個時候queue應該正在執行中)。在block對象以外調用這個函數會返回應用的默認併發queue。
2> 使用dispatch_get_main_queue函數得到應用主線程關聯的串行dispatch queue
備註:在新建立的子線程中,須要添加自動釋放池來管理內存。
GCD支持Cocoa內存管理機制,所以能夠在提交到queue的 block中自由地使用Objective-C對象。每一個dispatch queue維護本身的autorelease pool確保釋放autorelease對象,可是queue不保證這些對象實際釋放的時間。若是應用消耗大量內存,而且建立大量autorelease 對象,你須要建立本身的autorelease pool,用來及時地釋放再也不使用的對象。url
3、暫停和繼續queuespa
咱們能夠使用dispatch_suspend函數暫 停一個queue以阻止它執行block對象;使用dispatch_resume函數繼續dispatch queue。調用dispatch_suspend會增長queue的引用計數,調用dispatch_resume則減小queue的引用計數。當引用 計數大於0時,queue就保持掛起狀態。所以你必須對應地調用suspend和resume函數。掛起和繼續是異步的,並且只在執行block之間(比 如在執行一個新的block以前或以後)生效。掛起一個queue不會致使正在執行的block中止。
4、案例
小編經過使用GCD的實現方法,經過URL來異步存儲圖片。
1 @implementation UIImageView (webCach) 2 - (void)setUIImageWithUrl:(NSURL*)url 3 { 4 //使用異步線程來下載 5 dispatch_queue_t queue = dispatch_queue_create("imageLoad", NULL); 6 dispatch_async(queue, ^{ 7 NSData *data = [NSData dataWithContentsOfURL:url]; 8 UIImage *image = [UIImage imageWithData:data]; 9 //主線程 10 dispatch_sync(dispatch_get_main_queue(), ^{ 11 self.image = image; 12 }); 13 }); 14 15 } 16 @end
1 - (void)viewDidLoad { 2 3 [super viewDidLoad]; 4 5 UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 320, 500)]; 6 [imageView setUIImageWithUrl:[NSURL URLWithString:@"http://s1.dwstatic.com/group1/M00/F5/00/f251b9aca3b84a55449f1083e9fe8cda.jpg"]]; 7 [self.view addSubview:imageView]; 8 9 }
當圖片異步加載完成後,就會展示出來。可是,第二次進入該界面,仍是要從新下載圖片,用戶體驗很差,且浪費資源(好比耗電)。
因而,考慮緩存已經下載的圖片。
小便的能力有限,歡迎大牛指正!!!