標籤:
一、多線程1、什麼是多線程
NSThread
(1)多線程可以同時處理多個任務的請求。如果要同時執行多個任務,需要開啟一個新的線程。程式執行的時候串列執行,如果多個任務執行是並存執行。
//建立新的線程1 NSThread *thread1 =[[NSThread alloc]initWithTarget:self selector:@selector(taska:) object:nil]; [thread1 start]; //建立新線程2 [NSThread detachNewThreadSelector:@selector(taskb:) toTarget:self withObject:nil];
(2)多線程能解決什麼問題?
//
本質上,主要是解決某個耗時的任務執行時出現的介面卡死的問題,保證多個任務可以同時執行,比如迅雷下載。
//
情境使用,如大麥網,有的圖片下載耗時5秒,或者載入1G的檔案,需要啟動多線程。
//
(3) 線程的同步以及鎖 示範問題
CPU從記憶體中拿出資料更改值然後放回記憶體,如果多線程訪問,結果可能不正確。解決方式是加鎖。
-(void)add{ for (int i=0; i<1000; i++) { [_lock lock]; _num ++; NSLog(@"add ==%d",_num); [_lock unlock]; }}-(void)sub{ for (int i=0; i<1000; i++) { [_lock lock]; _num --; NSLog(@"sub ==%d",_num); [_lock unlock]; }}
項目開發中,noatomic當一個屬性只有UI介面訪問可以加,提高訪問速度。如果這個屬性會被建立的子線程訪問時不要加noatomic保證線程的安全。
UI線程稱為主線程,其他建立的線程稱為工作子線程
注意:不要在子線程中直接操作UI
{ .......
///子線程如何更新UI(重要),避免代碼出問題。eg:下載進度更新 ///UI線程稱為主線程,其他建立的線程稱為工作子線程,注意:不要在子線程中直接操作UI(間接讓主線程操作UI) _progressView =[[UIProgressView alloc] initWithFrame:CGRectMake(50, 200, 250, 10)]; [self.view addSubview:_progressView]; [NSThread detachNewThreadSelector:@selector(downloadNetworkingData) toTarget:self withObject:nil]; }#pragma mark --示範下載資料-(void)downloadNetworkingData{//類比10s網路下載 for (int i=0; i<100; i++) { //_progressView.progress +=0.01;不要在這裡操作UI介面 // 以下語句是間接操作UI的過程 [self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:YES]; [NSThread sleepForTimeInterval:0.1]; }}-(void)updateUI{_progressView.progress +=0.01;}
二、NSOpetation
1、什麼是NSOperation
也是實現多線程的一種機制,在NSThread做了更高的抽象,加入了Block,比NSThread簡單易用
三 、GCD
1、Grand Central Dispatch 簡寫
優點:支援多核心,C和BLOCK介面,便於使用,功能強大。
1.建立一個非同步任務 [ self creatAsyncTask];2.類比網路下載 [self simulateNewokingDownload];3.只是執行一次 [self runOnce]; 4。延時執行 [self delayRun]; 5 通知執行多個任務,等待所有任務執行完成時進行處理 [self groupRun]; ===============-(void)groupRun{ //group 工作群組 dispatch_group_t group =dispatch_group_create(); //新增工作,7秒完成 dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // for (int i=0; i<100; i++) { NSLog(@"A=%d",i); [NSThread sleepForTimeInterval:0.07]; } }); //新增工作,5秒完成 dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // for (int i=0; i<100; i++) { NSLog(@"B=%d",i); [NSThread sleepForTimeInterval:0.05]; } }); //新增工作,10秒完成 dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // for (int i=0; i<100; i++) { NSLog(@"C=%d",i); [NSThread sleepForTimeInterval:0.1]; } });// 監控完成後的操作 dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSLog(@"全部任務完成了"); });}-(void)delayRun{ //5s後輸出 dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(5*NSEC_PER_SEC) ), dispatch_get_main_queue(), ^{ // NSLog(@"haha"); });}-(void)runOnce{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSLog(@"只執行一次的代碼");});}-(void)simulateNewokingDownload{ _progressView =[[UIProgressView alloc] initWithFrame:CGRectMake(50, 200, 250, 10)]; [self.view addSubview:_progressView]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ for (int i=0; i<10; i++) { // //最後顯示對話方塊 dispatch_async(dispatch_get_main_queue(), ^{ _progressView.progress +=0.1; }); [NSThread sleepForTimeInterval:1]; } dispatch_async(dispatch_get_main_queue(), ^{ UIAlertView *alertView =[[UIAlertView alloc] init]; alertView.message [email protected]"下載完成"; [alertView addButtonWithTitle:@"取消"]; [alertView show]; }); });}#pragma mark --GCD測試方法-(void)creatAsyncTask{ //建立一個非同步任務,參數1,傳入queue,有3種queue: main queue 主隊列 ;global queue 全域隊列,背景工作執行緒;自訂queue dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(queue, ^{ for (int i=0; i<20; i++) { NSLog(@"A===%d",i); } }); dispatch_async(queue, ^{ for (int i=0; i<20; i++) { NSLog(@"B===%d",i); } });}
IOS之多線程