優勢:多線程
NSThread 比其餘兩個輕量級、使用方便、簡潔。併發
缺點:異步
①須要本身管理線程的生命週期。async
②線程同步,線程同步對數據的加鎖會有必定的系統開銷oop
NSThread線程的使用:url
啓動一個線程spa
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(myThreadTask) object:nil]; thread.name=@"sum"; [thread start]
中止線程.net
[thread cancel]; thread = nil;
注意:中止線程的並非直接殺死線程,而是設置了個標記線程
-(void) myThreadTask{ @autoreleasepool { NSLog(@"Thread Entry Point"); while ([[NSThread currentThread] isCancelled] == NO){ [NSThread sleepForTimeInterval:10]; NSLog(@"Thread Loop"); } NSLog(@"Thread Finished"); } }
還有一類用法以下:code
[NSThread detachNewThreadSelector:@selector(bigDemo) toTarget:self withObject:nil];
優勢:
① 底層實現自GCD,相對高效
② 內部線程池能夠更好的管理子線程
③能夠設置線程執行的優先級和依賴關係
NSOperation的用法:
1.無依賴關係
NSOperationQueue *queue = [[NSOperationQueue alloc] init]; NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^(){ NSLog(@"執行第1次操做,線程:%@", [NSThread currentThread]); }]; NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^(){ NSLog(@"執行第2次操做,線程:%@", [NSThread currentThread]); }]; [queue addOperation:operation1]; [queue addOperation:operation2];
2.設置依賴關係
NSOperationQueue *queue = [[NSOperationQueue alloc] init]; NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^(){ NSLog(@"執行第1次操做,線程:%@", [NSThread currentThread]); }]; NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^(){ NSLog(@"執行第2次操做,線程:%@", [NSThread currentThread]); }]; // operation1依賴於operation2 [operation1 addDependency:operation2]; //那麼2先執行,接下來1才能執行 [queue addOperation:operation1]; [queue addOperation:operation2];
3.設置線程最大併發數量,通常併發量取決於cpu核心數
queue.maxConcurrentOperationCount = 3;
GCD的底層依然是用線程實現,讓程序平行排隊的特定任務,根據可用的處理資源,安排他們在任何可用的處理器核心上執行任務。
優勢:
①高效、能夠選擇各類隊列
②可擴展性高
缺點:
①沒法實現多線程同步,線程同步須要藉助信號量來實現
②沒法直接取消指定的任務
GCD使用場景一:
單例
+ (instancetype)defaultViewController { static ViewController *vc = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ vc = [[ViewController alloc] init]; }); return vc; }
圖片異步加載的實現
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{ NSURL*url = [NSURLURLWithString:@"http://img5.netease.com/img/20151030124521.jpg"]; NSData*data = [NSDatadataWithContentsOfURL:url]; UIImage*image = [UIImageimageWithData:data]; // GCD返回主線程UI賦值 dispatch_sync(dispatch_get_main_queue(), ^{ self.imageView.image= image; }); });
併發
dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //請求1 NSLog(@"Request_1"); }); dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //請求2 NSLog(@"Request_2"); }); dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //請求3 NSLog(@"Request_3"); }); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ //界面刷新 NSLog(@"任務均完成,刷新界面"); });
經過barrier控制併發量
barrier:表示柵欄,當在併發隊列裏面使用柵欄時候,柵欄以前的併發任務開始併發執行,執行完畢後,執行柵欄內的任務,等柵欄任務執行完畢後,再併發執行柵欄後的任務。
dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT); dispatch_async(concurrentQueue, ^(){ NSLog(@"dispatch-1"); }); dispatch_async(concurrentQueue, ^(){ NSLog(@"dispatch-2"); }); dispatch_barrier_async(concurrentQueue, ^(){ NSLog(@"dispatch-barrier"); }); dispatch_async(concurrentQueue, ^(){ NSLog(@"dispatch-3"); }); dispatch_async(concurrentQueue, ^(){ NSLog(@"dispatch-4"); });
普通對象
MyThread *newThread = [[MyThread alloc] init]; NSObject * plainObject = newThread; [plainObject performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:YES]
NSOperation
NSBlockOperation *b=[NSBlockOperation blockOperationWithBlock:^{ NSLog(@"%@",[NSThread currentThread]); }]; [[NSOperationQueue mainQueue]addOperation:b];
dispatch
dispatch_sync(dispatch_get_main_queue(), ^{ self.imageView.image= image; });