iOS 使用多線程

iOS 中實(shí)現(xiàn)多線程的方法有很多,基于C的有pthread,GCD,基于OC的有NSThread,NSOperationQueue,后者是前者的封裝,執(zhí)行效率較差,推薦使用GCD,下面介紹下開啟線程的方法。

pthread

// 創(chuàng)建線程    
pthread_t myRestrict;    
pthread_create(&myRestrict, NULL, run, NULL);
// 方法實(shí)現(xiàn)
void *run(void *data){   
    for (int i = 0; i<10000; i++){                                           
       NSLog(@"%d---%@", i, [NSThread currentThread]);    
    }    
    return NULL;
}   

Thread

方法一
// 創(chuàng)建線程   
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(download:) object:@"http://b.png"];    
thread.name = @"下載線程";      
// 啟動(dòng)線程(調(diào)用self的download方法)    
[thread start];
- (void)download:(NSString *)url{   
    NSLog(@"下載---%@---%@", url, [NSThread currentThread]);
}
方法二
[NSThread detachNewThreadSelector:@selector(download:) toTarget:self withObject:@"http://a.jpg"];
- (void)download:(NSString *)url{   
    NSLog(@"下載---%@---%@", url, [NSThread currentThread]);
}
方法三
// 這2個(gè)不會(huì)創(chuàng)建線程,在當(dāng)前線程中執(zhí)行
// [self performSelector:@selector(download:) withObject:@"http://c.gif"];
// [self download:@"http://c.gif"]; 
// 這個(gè)方法會(huì)創(chuàng)建線程      
[self performSelectorInBackground:@selector(download:) withObject:@"http://c.gif"];
- (void)download:(NSString *)url{   
    NSLog(@"下載---%@---%@", url, [NSThread currentThread]);
}

GCD

async : 并發(fā)隊(duì)列(最常用)
會(huì)不會(huì)創(chuàng)建線程:會(huì),一般同時(shí)開多條
任務(wù)的執(zhí)行方式:并發(fā)執(zhí)行

// 獲得全局的并發(fā)隊(duì)列    
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);       
// 將任務(wù)添加全局隊(duì)列中去異步執(zhí)行    
dispatch_async(queue, ^{       
 NSLog(@"-----下載圖片1---%@", [NSThread currentThread]);    
});    
dispatch_async(queue, ^{        
NSLog(@"-----下載圖片2---%@", [NSThread currentThread]);
});

async : 串行隊(duì)列(有時(shí)候用)
會(huì)不會(huì)創(chuàng)建線程:會(huì),一般只開1條線程
任務(wù)的執(zhí)行方式:串行執(zhí)行(一個(gè)任務(wù)執(zhí)行完畢后再執(zhí)行下一個(gè)任務(wù))

// 1.創(chuàng)建一個(gè)串行隊(duì)列   
dispatch_queue_t queue = dispatch_queue_create("cn.test.queue", NULL);       
// 2.將任務(wù)添加到串行隊(duì)列中 異步 執(zhí)行    
dispatch_async(queue, ^{        
NSLog(@"-----下載圖片1---%@", [NSThread currentThread]);    
});   
 dispatch_async(queue, ^{        
NSLog(@"-----下載圖片2---%@", [NSThread currentThread]);
});
// 3.非ARC,需要釋放創(chuàng)建的隊(duì)列
// dispatch_release(queue);

async -- 主隊(duì)列(很常用)

// 1.主隊(duì)列(添加到主隊(duì)列中的任務(wù),都會(huì)自動(dòng)放到主線程中去執(zhí)行)    
dispatch_queue_t queue = dispatch_get_main_queue();       
// 2.添加任務(wù)到主隊(duì)列中異步執(zhí)行(結(jié)果還是串行)    
dispatch_async(queue, ^{       
     NSLog(@"-----下載圖片1---%@", [NSThread currentThread]);    
});    
dispatch_async(queue, ^{        
    NSLog(@"-----下載圖片2---%@", [NSThread currentThread]);
});

sync -- 主隊(duì)列(不能用---會(huì)卡死)

NSLog(@"syncMainQueue----begin--");       
// 1.主隊(duì)列(添加到主隊(duì)列中的任務(wù),都會(huì)自動(dòng)放到主線程中去執(zhí)行)    
dispatch_queue_t queue = dispatch_get_main_queue();       
// 2.添加 任務(wù) 到主隊(duì)列中 同步 執(zhí)行    
dispatch_sync(queue, ^{        
    NSLog(@"-----下載圖片1---%@", [NSThread currentThread]);    
});    
dispatch_sync(queue, ^{        
    NSLog(@"-----下載圖片2---%@", [NSThread currentThread]);
});

sync -- 并發(fā)隊(duì)列
會(huì)不會(huì)創(chuàng)建線程:不會(huì)
任務(wù)的執(zhí)行方式:串行執(zhí)行(一個(gè)任務(wù)執(zhí)行完畢后再執(zhí)行下一個(gè)任務(wù))
并發(fā)隊(duì)列失去了并發(fā)的功能

// 獲得全局的并發(fā)隊(duì)列    
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);       
// 將 任務(wù) 添加到 全局并發(fā)隊(duì)列 中 同步 執(zhí)行    
dispatch_sync(queue, ^{        
    NSLog(@"-----下載圖片1---%@", [NSThread currentThread]);    
});   
dispatch_sync(queue, ^{        
    NSLog(@"-----下載圖片2---%@", [NSThread currentThread]);
});

sync -- 串行隊(duì)列
會(huì)不會(huì)創(chuàng)建線程:不會(huì)
任務(wù)的執(zhí)行方式:串行執(zhí)行(一個(gè)任務(wù)執(zhí)行完畢后再執(zhí)行下一個(gè)任務(wù))

// 創(chuàng)建一個(gè)串行隊(duì)列    
dispatch_queue_t queue = dispatch_queue_create("cn.text.queue", NULL);      
 // 將 任務(wù) 添加到 串行隊(duì)列 中 同步 執(zhí)行   
 dispatch_sync(queue, ^{       
     NSLog(@"-----下載圖片1---%@", [NSThread currentThread]);   
 });    
dispatch_sync(queue, ^{        
    NSLog(@"-----下載圖片2---%@", [NSThread currentThread]);
});

NSOperationQueue

基本用法

// 1.創(chuàng)建一個(gè)隊(duì)列(非主隊(duì)列)   
 NSOperationQueue *queue = [[NSOperationQueue alloc] init];       
// 2.添加操作到隊(duì)列中(自動(dòng)異步執(zhí)行任務(wù),并發(fā))    
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{        
   NSLog(@"下載圖片1---%@", [NSThread currentThread]);    
}];    
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{        
   NSLog(@"下載圖片2---%@", [NSThread currentThread]);    
}];       
[queue addOperation:operation1];   
[queue addOperation:operation2];   
[queue addOperationWithBlock:^{       
NSLog(@"下載圖片3---%@", [NSThread currentThread]);}];       
// 2個(gè)操作并發(fā)執(zhí)行

最大并發(fā)數(shù)

// 1.創(chuàng)建一個(gè)隊(duì)列(非主隊(duì)列)
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 2.設(shè)置最大并發(fā)(最多同時(shí)并發(fā)執(zhí)行3個(gè)任務(wù))
 queue.maxConcurrentOperationCount = 3;
// 3.添加操作到隊(duì)列中(自動(dòng)異步執(zhí)行任務(wù),并發(fā))    
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{        
    NSLog(@"下載圖片1---%@", [NSThread currentThread]);    
}];    
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{       
     NSLog(@"下載圖片2---%@", [NSThread currentThread]);   
 }];   
 NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{        
    NSLog(@"下載圖片3---%@", [NSThread currentThread]);
}];
NSInvocationOperation *operation4 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil];

[queue addOperation:operation1];    
[queue addOperation:operation2];    
[queue addOperation:operation3];
[queue addOperation:operation4];
   
[queue addOperationWithBlock:^{
      NSLog(@"下載圖片5---%@", [NSThread currentThread]);    }];    
[queue addOperationWithBlock:^{        
NSLog(@"下載圖片6---%@", [NSThread currentThread]);
    }];
//[queue cancelAllOperations];

設(shè)置依賴

/**  假設(shè)有A、B、C三個(gè)操作,
要求:1. 3個(gè)操作都異步執(zhí)行     
     2. 操作C依賴于操作B    
     3. 操作B依賴于操作A     
**/       
// 1.創(chuàng)建一個(gè)隊(duì)列(非主隊(duì)列)   
NSOperationQueue *queue = [[NSOperationQueue alloc] init];       // 2.創(chuàng)建3個(gè)操作    
NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{        
    NSLog(@"A1---%@", [NSThread currentThread]);    
}];    
//    [operationA cancel];//取消單個(gè)    
//    [operationA addExecutionBlock:^{    
//     NSLog(@"A2---%@", [NSThread currentThread]);    
//    }];       
//    [operationA setCompletionBlock:^{    
//        NSLog(@"AAAAA---%@", [NSThread currentThread]);    
//    }];       
NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{        
NSLog(@"B---%@", [NSThread currentThread]);    
}];   
 NSBlockOperation *operationC = [NSBlockOperation blockOperationWithBlock:^{        
NSLog(@"C---%@", [NSThread currentThread]);   
 }];       
// 設(shè)置依賴    
[operationB addDependency:operationA];    
[operationC addDependency:operationB];       
// 3.添加操作到隊(duì)列中(自動(dòng)異步執(zhí)行任務(wù))    
[queue addOperation:operationC];    
[queue addOperation:operationA];    
[queue addOperation:operationB];

異步回主線程

NSOperationQueue *queue = [[NSOperationQueue alloc] init];       
[queue addOperationWithBlock:^{        
  // 1.異步下載圖片       
  NSURL *url = [NSURL   URLWithString:@"http://d.hiphotos.baidu.com/image/pic/item/37d3d539b6003af3290eaf5d362ac65c1038b652.jpg"];        
  NSData *data = [NSData dataWithContentsOfURL:url];        
  UIImage *image = [UIImage imageWithData:data];               
  // 2.回到主線程,顯示圖片(三種方法)//        
  [self performSelectorOnMainThread:<#(SEL)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>];
//  dispatch_async(dispatch_get_main_queue(), ^{
//            
//        });        
  [[NSOperationQueue mainQueue] addOperationWithBlock:^{            
    self.imageView.image = image;        
  }];
}];

NSInvocationOperation

// 創(chuàng)建隊(duì)列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 創(chuàng)建操作
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil];
 // operation直接調(diào)用start,是同步執(zhí)行(在當(dāng)前線程執(zhí)行操作)
// [operation start];
   
// 添加操作到隊(duì)列中,會(huì)自動(dòng)異步執(zhí)行
[queue addOperation:operation];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 原文:http://www.cocoachina.com/ios/20170707/19769.html 本文主要...
    冬的天閱讀 2,431評論 0 12
  • 在這篇文章中,我將為你整理一下 iOS 開發(fā)中幾種多線程方案,以及其使用方法和注意事項(xiàng)。當(dāng)然也會(huì)給出幾種多線程的案...
    張戰(zhàn)威ican閱讀 699評論 0 0
  • 多線程 在iOS開發(fā)中為提高程序的運(yùn)行效率會(huì)將比較耗時(shí)的操作放在子線程中執(zhí)行,iOS系統(tǒng)進(jìn)程默認(rèn)啟動(dòng)一個(gè)主線程,用...
    郭豪豪閱讀 2,726評論 0 4
  • 都說魚的記憶只有七秒鐘,可是,我卻發(fā)現(xiàn),魚缸里有兩只魚,互相追逐的,永遠(yuǎn)是那兩條,那么,我是否可以理解成,他們在每...
    傾心藍(lán)田閱讀 306評論 0 0
  • 第一次加班。至晚上8點(diǎn)。正常是4點(diǎn)下班,但加班更正常。 大家都喜歡加班,因?yàn)楣べY會(huì)多很多。 決定還是要每天去圖書室...
    步驚魚閱讀 384評論 0 0

友情鏈接更多精彩內(nèi)容