標籤:
1.NSThread
①.開線程的幾種方式
*先建立, 後啟動
//開啟線程 NSThread *thread =[[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil]; //啟動 [thread start]; //直接啟動 [NSThread detachNewThreadSelector:@selector(<#selector#>) toTarget:self withObject:nil];
②.其他用法
//擷取當前線程 NSThread *current =[NSThread currentThread]; //獲得主線程 + (NSThread* )mainThread; //線程間通訊 (從子線程回到主線程)
- (void)performSelectorOnMainThread:<#(SEL)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>
CGD(重點)
1.隊列的類型
*並發隊列:可以同時執行多個任務
獲得全域的並發隊列:dispatch_get_global_queue(<#long identifier#>, <#unsigned long flags#>)
*串列隊列:一個任務執行完了才能執行下一個任務
a.自己建立:dispatch_queue_create
b.主隊列:dispatch_get_main_queue
2.執行任務的方法類型
*同步(sync)執行:只能在當前線程執行任務
*非同步(async)執行:可以多個線程執行任務(系統會自動給你開闢的,你只要寫要做什麼)
3.瞭解隊列的方法配合使用
*非同步並發隊列
//擷取全域的並發隊列 //第一個參數代表優先順序 dispatch_queue_t queue= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //2.新增工作到隊列中,執行 任務 dispatch_async(queue, ^{ NSLog(@"------下載圖片1-------%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"------下載圖片1-------%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"------下載圖片1-------%@",[NSThread currentThread]); }); //總結:同時開啟了3個線程
*非同步串列隊列
//1.建立串列隊列 dispatch_queue_t queue= dispatch_queue_create("com.itheima.queue ", NULL); dispatch_async(queue, ^{ NSLog(@"------下載圖片1-------%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"------下載圖片1-------%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"------下載圖片1-------%@",[NSThread currentThread]); }); //總結:只會開一個線程;
*同步串列
//建立串列隊列 dispatch_queue_t queue=dispatch_queue_create("wangbinbin.queue", NULL); //2.新增工作到隊列中,執行 任務 dispatch_sync(queue, ^{ NSLog(@"------下載圖片1-------%@",[NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"------下載圖片2-------%@",[NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"------下載圖片3-------%@",[NSThread currentThread]); }); //總結:不會開闢線程 只在當前線程執行(當前線程為主線程, dispatch_sync是在主線程)
*同步並發隊列
//擷取全域的並發隊列 //第一個參數代表優先順序 dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //2.新增工作到隊列中,執行 任務 dispatch_sync(queue, ^{ NSLog(@"------下載圖片1-------%@",[NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"------下載圖片2-------%@",[NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"------下載圖片2-------%@",[NSThread currentThread]); }); //總結:不會開啟新的線程,並發隊列失去了並發功能
GCD其他常用方法
1.從子線程回到主線程
NSLog(@"%@",[NSThread currentThread]); //非同步並發隊列 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSLog(@"------%@",[NSThread currentThread]); //請求圖片 NSURL *url =[NSURL URLWithString:@"http://img.taopic.com/uploads/allimg/110812/1820-110Q20K01549.jpg"]; NSData *data =[NSData dataWithContentsOfURL:url]; UIImage *image=[UIImage imageWithData:data]; //回到主線程顯示圖片 dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"+++%@",[NSThread currentThread]); self.imgView.image=image; }); });
2.一次性代碼
//一次性代碼 單例裡面用得到 static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSLog(@"只執行一次,"); });
3.延時操作
//延時操作 2秒後 //計算時間 dispatch_time_t when=dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)); //會在when這個時間點,執行queue(隊列可以自己選擇) dispatch_after(when, dispatch_get_main_queue(), ^{ NSLog(@"瞧我!!"); });
4.隊列組
有這麼一種需求
首先:分別非同步執行2個耗時的操作
其次:等2個非同步作業都執行完畢後,再回到主線程執行操作
//建立一個組 dispatch_group_t group =dispatch_group_create(); //開啟一個任務下載圖片1 __block UIImage *image1 =nil; dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ image1 =[self requestImageWithUrl:@"http://d.hiphotos.baidu.com/image/pic/item/faedab64034f78f09c7428247d310a55b2191ced.jpg"]; }); //開啟一個任務下載圖片2 __block UIImage *image2 =nil; dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ image2 =[self requestImageWithUrl:@"http://b.hiphotos.baidu.com/image/h%3D360/sign=502eb6fad954564efa65e23f83df9cde/80cb39dbb6fd5266c96cb6fdaf18972bd5073697.jpg"]; }); //等group中的所有任務都執行完畢,在執行其他動作 dispatch_group_notify(group, dispatch_get_main_queue(), ^{ self.UIImageView1.image=image1; self.UIImageView2.image=image2; //合并2個image UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 100), NO, 0); [image1 drawInRect:CGRectMake(0, 0, 100, 100)]; [image2 drawInRect:CGRectMake(100, 0, 100, 100)]; self.bigUiImageView.image=UIGraphicsGetImageFromCurrentImageContext(); //關閉上下文 UIGraphicsEndImageContext(); });
iOS 多線程( GCD NSThread )