IOS之多线程
?
一、多線程
1、什么是多線程
NSThread
(1)多線程可以同時處理多個任務的請求。如果要同時執行多個任務,需要開啟一個新的線程。程序執行的時候串行執行,如果多個任務執行是并行執行。
//創建新的線程1NSThread *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 =@"下載完成"; [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); } }); }?
轉載于:https://www.cnblogs.com/jayzhang/p/4427701.html
總結
- 上一篇: RHEL 6.3使用CentOS yum
- 下一篇: 关于宏定义