IOS 多線程

一、NSObject的多線程方法——後臺線程程序員

二、NSThread 每一個NSThread對象對應一個線程,量級較輕(真正的多線程)
如下兩點是蘋果專門開發的「併發」技術,使得程序員能夠再也不去關心線程的具體使用問題
三、NSOperation/NSOperationQueue 面向對象的線程技術
四、GCD —— Grand Central Dispatch(派發) 是基於C語言的框架,能夠充分利用多核,是蘋果推薦使用的多線程技術編程

NSThread:
優勢:NSThread 比其餘兩個輕量級,使用簡單
缺點:須要本身管理線程的生命週期、線程同步、加鎖、睡眠以及喚醒等。線程同步對數據的加鎖會有必定的系統開銷
多線程

NSOperation:
不須要關心線程管理,數據同步的事情,能夠把精力放在本身須要執行的操做上
NSOperation是面向對象的
併發

工做原理:
用NSOperation封裝要執行的操做
將建立好的NSOperation對象放NSOperationQueue中
啓動OperationQueue開始新的線程執行隊列中的操做
注意事項:
使用多線程時一般須要控制線程的併發數,由於線程會消耗系統資源,同時運行的線程過多,系統會變慢app


GCD:
Grand Central Dispatch是由蘋果開發的一個多核編程的解決方案。iOS4.0+才能使用,是替代NSThread, NSOperation的高效和強大的技術
GCD是基於C語言的框架

工做原理:
讓程序平行排隊的特定任務,根據可用的處理資源,安排它們在任何可用的處理器上執行任務
要執行的任務能夠是一個函數或者一個block
底層是經過線程實現的,不過程序員能夠沒必要關注實現的細節
GCD中的FIFO隊列稱爲dispatch queue,能夠保證先進來的任務先獲得執行
dispatch_notify 能夠實現監聽一組任務是否完成,完成後獲得通知
GCD隊列:
全局隊列:全部添加到主隊列中的任務都是併發執行的
串行隊列:全部添加到串行隊列中的任務都是順序執行的
主隊列:全部添加到主隊列中的任務都是在主線程中執行的異步

全局隊列(可能會開啓多條線程)
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
串行隊列(只可能會開啓一條線程)
dispatch_queue_t queue = dispatch_queue_create(「myQueue」, DISPATCH_QUEUE_SERIAL);
主隊列
dispatch_get_main_queue();async

異步操做
dispatch_async 在其餘線程執行任務,會開啓新的線程
異步方法沒法肯定任務的執行順序
同步操做
dispatch_sync 在當前在當前線程執行任務,不開啓新的線程
同步操做與隊列無關
同步方法會依次執行,可以決定任務的執行順序
更新界面UI時,最好使用同步方法函數

GCD的優勢:
充分利用多核
全部的多線程代碼集中在一塊兒,便於維護
GCD中無需使用@autoreleasepool
若是要順序執行,能夠使用dispatch_sync同步方法spa

NSObject

 //在後臺執行(最簡單)

    [self performSelectorInBackground:@selector(test) withObject:nil];


NSThread

    //NSThread是一個輕量級的多線程,有如下兩種方式建立。
   
//1.初始化並手動開啓子線程
//    NSThread *thread =[[NSThread alloc]initWithTarget:self selector:@selector(test) object:nil];
//    //開啓子線程
//    [thread start];
//    //取消子線程
//    [thread cancel];
   
   
//2.初始化的同時開啓子線程

    [NSThread detachNewThreadSelector:@selector(test) toTarget:self withObject:nil];

NSOperation

    //NSOperactionMVC裏面屬於M層,用來封裝單個任務的數據和相關代碼的抽象類,咱們通常使用他的子類NSInvocationOperationNSBlockOperation
   
//NSOperation自己並沒有主線程,子線程之分,只是一個操做,一般與NSOperationQueue結合使用
   
NSInvocationOperation *invoOperaction = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test) object:nil];
   
__weak typeof(self)temp = self;
   
//    __weak ViewController *temp1 = self;
   
   
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
        [temp
test];
       
NSLog(@"這是BLOCK執行的");
    }];
   
//nsoperationQueue是線程操做列隊,用來管理一組NSOperationQueue,會根據需求建立出適合數量的子線程,完成任務的併發執行
   
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    [queue
addOperation:invoOperaction];
    [queue
addOperation:blockOperation];
   
//設置最大併發執行數,當數量爲1的時候,線程編程同步執行(串行)

    [queue setMaxConcurrentOperationCount:2];

GCD

    //GCD有三種列隊
   
/*
     1,
主列隊(串行)
     2
,全局列隊(並行)
     3
,自定義列隊(串行列隊,並行列隊)
     */

   
//,主列隊
   
//獲取主列隊(生成了一個串行的隊列,隊列裏面的block按照FIFO(先進後出)的順序執行,實際上爲單線程隊列)
   
dispatch_queue_t mainQueue = dispatch_get_main_queue();
   
__weak typeof(self)temp = self;
/*
    //
向列隊添加任務
    dispatch_async(mainQueue, ^{
        [temp test];
        NSLog(@"1
%@--%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
    });
//    dispatch_async(mainQueue, ^{
//        [temp test];
//        NSLog(@"2
%@--%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);

//    });

    //定義時間
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"
無語");
    });
*/

   
   
//全局列隊(並行)
   
dispatch_queue_t global = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
   
dispatch_async(global, ^{
        [temp
test];
       
NSLog(@"1:%@--%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
    });
   
dispatch_async(global, ^{
        [temp
test];
       
NSLog(@"2:%@--%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
    });
   
   
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), global, ^{
       
NSLog(@"4");
    });
   
   
//指定次數,將指定的block加入到指定的隊列裏面,並等待所有執行完畢。
   
//1參數:指定重複次數
   
//2.參數:指定隊列
   
//3.參數:
   
dispatch_apply(5, global, ^(size_t t) {
       
NSLog(@"執行次數:%zu",t);
    });
   
//主隊列只能串行執行,全局隊列只能並行執行,且他們都是單列
   
//自定義隊列
   
//1.參數:隊列的名稱
   
//2.參數:指定隊列列行
   
dispatch_queue_t queue1 = dispatch_queue_create("AAA", DISPATCH_QUEUE_SERIAL);
   
   
dispatch_async(queue1, ^{
       
NSLog(@"我是第一個");
        [temp
test];
    });
   
dispatch_async(queue1, ^{
       
NSLog(@"我是第二個");
        [temp
test];
    });
   
//添加函數
   
dispatch_async_f(queue1, "context", function);
   
//添加延時block
   
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), queue1, ^{
       
NSLog(@"等的都快發黴了。");
    });
   
//添加劇復
   
dispatch_apply(5, queue1, ^(size_t t) {
       
//輸入想重複操做的代碼
       
NSLog(@"a");

    });

相關文章
相關標籤/搜索