GCD 是iOS多線程實現方案之一,非常常用 英文翻譯過來就是偉大的中樞調度器,也有人戲稱為是牛逼的中樞調度器 是蘋果公司為多核的並行運算提出的解決方案 1.一次性函數 dispatch_once 顧名思義是只執行一次的函數,註意是整個程式中只執行一次(單例模式常用到) 2.柵欄函數 dispatc ...
GCD
是iOS多線程實現方案之一,非常常用
英文翻譯過來就是偉大的中樞調度器,也有人戲稱為是牛逼的中樞調度器
是蘋果公司為多核的並行運算提出的解決方案
1.一次性函數
dispatch_once
顧名思義是只執行一次的函數,註意是整個程式中只執行一次(單例模式常用到)
- (void)once { //一次性函數,只執行函數 static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ //裡面預設線程安全的 NSLog(@"------run"); }); }
2.柵欄函數
dispatch_barrier_async
作用就是控制多線程的執行順序
- (void)barrier { dispatch_queue_t queue = dispatch_queue_create("123", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ NSLog(@"_______1--------%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"_______2--------%@",[NSThread currentThread]); }); //像柵欄一樣,讓上面的先執行完,再執行下麵的 dispatch_barrier_async(queue, ^{ NSLog(@"----barrier-----%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"_______3--------%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"_______4--------%@",[NSThread currentThread]); }); }
3.快速迭代函數
dispatch_apply
作用就是開啟多個線程同時完成某一件事,例如同時下載多張圖片
//一般的做法 - (void)cutFromFileTo { //一般在子線程中做 //創建並行隊列 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(queue, ^{ //起始路徑 NSString *from = @"/Users/DDZ/Desktop/From"; //目標路徑 NSString *to = @"/Users/DDZ/Desktop/To"; NSFileManager *mgr = [NSFileManager defaultManager]; //獲取起始路徑中所有文件路徑 NSArray *subpaths = [mgr subpathsAtPath:from]; for (int i = 0; i < subpaths.count; i++) { //將路徑字元串進行拼接 NSString *fromFullPath = [NSString stringWithFormat:@"%@/%@",from,subpaths[i]]; NSString *toFullPath = [NSString stringWithFormat:@"%@/%@",to,subpaths[i]]; [mgr moveItemAtPath:fromFullPath toPath:toFullPath error:nil]; } NSLog(@"剪切成功"); }); }View Code
//使用快速迭代進行剪切 - (void)cutFileApply { //起始路徑 NSString *from = @"/Users/DDZ/Desktop/From"; //目標路徑 NSString *to = @"/Users/DDZ/Desktop/To"; NSFileManager *mgr = [NSFileManager defaultManager]; //獲取起始路徑中所有文件路徑 NSArray *subpaths = [mgr subpathsAtPath:from]; dispatch_apply(subpaths.count, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t index) { NSString *subpath = subpaths[index]; //將路徑字元串進行拼接 NSString *fromFullPath = [NSString stringWithFormat:@"%@/%@",from,subpath]; NSString *toFullPath = [NSString stringWithFormat:@"%@/%@",to,subpath]; //剪切 [mgr moveItemAtPath:fromFullPath toPath:toFullPath error:nil]; }); }
一般的方法只能一張圖片剪切完之後,再進行下一張得剪切
而使用快速迭代則可以同時進行剪切。
4.隊列組
dispatch_group_async
與柵欄函數有相同的目的,為了控制多線程的執行順序
例如下載兩張圖片之後,再將這兩者合併成新的圖片並顯示。
必須得先下完之後才能合併吧!(順序問題,多線程是不可控的)
//隊列組 - (void)group { //創建組 dispatch_group_t group = dispatch_group_create(); dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //1.下載圖片1 dispatch_group_async(group, queue, ^{ //實現下載 NSURL *url = [NSURL URLWithString:@"http://g.hiphotos.baidu.com/image/pic/item/6c224f4a20a446230761b9b79c22720e0df3d7bf.jpg"]; NSData *data = [NSData dataWithContentsOfURL:url]; //生成圖片 self.img1 = [UIImage imageWithData:data]; }); //2.下載圖片2 dispatch_group_async(group, queue, ^{ //實現下載 NSURL *url = [NSURL URLWithString:@"http://h.hiphotos.baidu.com/image/pic/item/b812c8fcc3cec3fd5b9db074d488d43f8794270b.jpg"]; NSData *data = [NSData dataWithContentsOfURL:url]; self.img2 = [UIImage imageWithData:data]; }); //3.將圖片1,圖片2合成一張新的圖片 dispatch_group_notify(group, queue, ^{ //開啟新的圖形上下文 UIGraphicsBeginImageContext(CGSizeMake(200, 200)); //繪製圖片 [self.img1 drawInRect:CGRectMake(0, 0, 100, 200)]; [self.img2 drawInRect:CGRectMake(100, 0, 100, 200)]; //取得上下文中的圖片 UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); //結束上下文 UIGraphicsEndImageContext(); //回到主線程顯示圖片 dispatch_async(dispatch_get_main_queue(), ^{ //4.將新圖片顯示出來 self.imageView.image = image; }); }); }View Code
5.延時(補充)
- (void)delay { //延時 NSLog(@"______"); [self performSelector:@selector(run) withObject:nil afterDelay:2.0]; } - (void)run { NSLog(@"end"); }