什麼是主線程? 一個iOS程式運行後,預設會開啟一條線程,稱為“主線程”或“UI線程” 主線程的主要作用 1.顯示/刷新UI界面 2.處理UI事件(比如點擊事件,滾動事件,拖拽事件) 主線程的使用註意 1.別將比較耗時的操作放在主線程中 2.耗時操作會卡在主線程中,嚴重影響UI的流暢程度 如圖,將耗 ...
什麼是主線程?
一個iOS程式運行後,預設會開啟一條線程,稱為“主線程”或“UI線程”
主線程的主要作用
1.顯示/刷新UI界面
2.處理UI事件(比如點擊事件,滾動事件,拖拽事件)
主線程的使用註意
1.別將比較耗時的操作放在主線程中
2.耗時操作會卡在主線程中,嚴重影響UI的流暢程度
如圖,將耗時操作放在主線程中,任務會按照串列順序執行,在第五秒點擊按鈕之後,界面會卡住5秒
因為耗時操作還沒有執行完,不能立即響應按鈕的點擊
1.pthread的使用
void *run(void *parme) { NSLog(@"%@",[NSThread currentThread]); for (int i = 0; i < 100000; i++) { NSLog(@"%d",i); } return NULL; } - (IBAction)btnClick:(id)sender { pthread_t thread; pthread_create(&thread, NULL, run, NULL); }
2.NSThread的使用
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { [self createThread3]; } //第一種創建方法 - (void)createThread1 { //需要幾個線程就alloc幾個 NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run:) object:@"第一種"]; thread.name = @"one_thread"; [thread start]; } //第二種創建方法 - (void)createThread2 { [NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@"第二種"]; } //第三種創建方法 - (void)createThread3 { [self performSelectorInBackground:@selector(run:) withObject:@"第三種"]; } - (void)run:(NSString *)param { NSLog(@"______%@_____%@",param,[NSThread currentThread]); }
3.GCD的使用
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { [self syncMain]; } /** 同步函數+主隊列 */ - (void)syncMain { dispatch_queue_t queue = dispatch_get_main_queue(); NSLog(@"syncMain ---- begin"); //將任務加入到隊列 dispatch_sync(queue, ^{ NSLog(@"1----%@",[NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"2----%@",[NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"3----%@",[NSThread currentThread]); }); NSLog(@"syncMain ---- end"); } /** 非同步函數+主隊列 */ - (void)asyncMain { //非同步函數用在主隊列上就不會開線程了 //獲得串列隊列 dispatch_queue_t queue = dispatch_get_main_queue(); //將任務加入到隊列 dispatch_async(queue, ^{ NSLog(@"1----%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"2----%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"3----%@",[NSThread currentThread]); }); } /** 同步函數+串列隊列:不會開啟新的線程,在當前線程執行任務 */ - (void)syncSerial { //創建串列隊列 dispatch_queue_t queue = dispatch_queue_create("com.520.queue", DISPATCH_QUEUE_SERIAL); //將任務加入到隊列 dispatch_sync(queue, ^{ NSLog(@"1----%@",[NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"2----%@",[NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"3----%@",[NSThread currentThread]); }); } /** 非同步函數+串列隊列:會開啟新的線程,但是任務是串列的,執行完一個任務,再執行下一個任務 */ - (void)asyncSerial { //創建串列隊列 dispatch_queue_t queue = dispatch_queue_create("com.520.queue", DISPATCH_QUEUE_SERIAL); //將任務加入到隊列 dispatch_async(queue, ^{ NSLog(@"1----%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"2----%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"3----%@",[NSThread currentThread]); }); } /** 同步函數+併發隊列:不會開啟線程,不能 */ - (void)syncConcurrent { //獲得全局的併發隊列 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //將任務添加到隊列 dispatch_async(queue, ^{ NSLog(@"1----%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"1----%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"1----%@",[NSThread currentThread]); }); } /** 非同步函數+併發隊列:可以同時開啟多條線程 */ - (void)asycConcurrent { //創建一個隊列 //第一個參數是標簽等同於名字 //第二個參數傳串列還是並行 // dispatch_queue_t queue = dispatch_queue_create("img.download", DISPATCH_QUEUE_CONCURRENT); //獲得全局的併發隊列 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //將任務添加到隊列 dispatch_async(queue, ^{ for (int i = 0; i < 10; i++) { NSLog(@"1----%@",[NSThread currentThread]); } }); //將任務添加到隊列 dispatch_async(queue, ^{ for (int i = 0; i < 10; i++) { NSLog(@"2----%@",[NSThread currentThread]); } }); //將任務添加到隊列 dispatch_async(queue, ^{ for (int i = 0; i < 10; i++) { NSLog(@"3----%@",[NSThread currentThread]); } }); }View Code
在使用GCD時,主要分為兩步
1.定製任務
2.將任務添加到隊列
這裡還需要區分下同步,非同步,並行,串列
同步非同步:影響是否開啟新的線程
並行串列:影響任務的執行方式