iOS進(jìn)階之多線程

進(jìn)程

  • 一個進(jìn)程有一個或多個線程組成。進(jìn)程只負(fù)責(zé)資源的調(diào)度和分配,線程才是程序正在的執(zhí)行單元,負(fù)責(zé)代碼的執(zhí)行。
  • 單線程 只有一個線程的程序,稱作為單線程程序。
  • 多線程 iOS允許用戶自己開辟新的線程,相當(dāng)于主線程來講。這些線程,稱為子線程;子線程和主線程都是獨立的運行單元,各自的執(zhí)行互不影響,因此能夠并發(fā)執(zhí)行。
  • iOS中關(guān)于UI的添加和刷新必須在主線程中操作

創(chuàng)建子線程

 //創(chuàng)建子線程
  self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(subThread:) object:@"子線程啟動"];
//啟動子線程
 [self.thread start];

GDC的學(xué)習(xí)

#pragma mark --- GCD的學(xué)習(xí)
//穿行隊列:所有的任務(wù)在隊里中順序執(zhí)行,相當(dāng)于在operationQueue中將最大并大數(shù)設(shè)置為1的效果
//并行隊列:所有的任務(wù)都是在隊列中并發(fā)執(zhí)行。
-(void)serialQueue{
    //創(chuàng)建穿行隊列
    //第一個參數(shù):當(dāng)前隊列的標(biāo)記
    //第二個參數(shù):當(dāng)前隊列的類型設(shè)置 DISPATCH_QUEUE_SERIAL宏定義的值為NULL
//    dispatch_queue_t sQueue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);
    
    //創(chuàng)建并行隊列
    dispatch_queue_t sQueue = dispatch_queue_create("conCurrent", DISPATCH_QUEUE_CONCURRENT);
    //創(chuàng)建任務(wù)添加到隊列中
    //第一個參數(shù):當(dāng)前任務(wù)所要添加進(jìn)的隊列
    //第二個參數(shù):block,要執(zhí)行的任務(wù)在block中執(zhí)行
    dispatch_async(sQueue, ^{
        NSLog(@"1----%@",[NSThread currentThread]);
    });
    dispatch_async(sQueue, ^{
        NSLog(@"2----%@",[NSThread currentThread]);
    });
    dispatch_async(sQueue, ^{
        NSLog(@"3----%@",[NSThread currentThread]);
    });
    dispatch_async(sQueue, ^{
        NSLog(@"4----%@",[NSThread currentThread]);
    });
    dispatch_async(sQueue, ^{
        NSLog(@"5----%@",[NSThread currentThread]);
    });
    dispatch_async(sQueue, ^{
        NSLog(@"6----%@",[NSThread currentThread]);
    });
}
//全局隊列 系統(tǒng)提供的一個并行隊列,該全局隊列,可以設(shè)置隊列優(yōu)先級
-(void)globalQueue{
    
    //第一個參數(shù):優(yōu)先級設(shè)置
    //第二個參數(shù):預(yù)留參數(shù),將來可能用到。目前直接賦值為0即可
    dispatch_queue_t gQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(gQueue, ^{
        NSLog(@"要執(zhí)行的耗時操作----%@",[NSThread currentThread]);
        //回主線程處理UI
        //先得到一個主隊列,將任務(wù)加入到主隊列,在主隊列執(zhí)行的任務(wù)肯定在主線程中。
        dispatch_queue_t mainQueue = dispatch_get_main_queue();
        dispatch_async(mainQueue, ^{
            NSLog(@"我回到主線程了----%@",[NSThread currentThread]);
        });
    });
    //簡便寫法。工作中經(jīng)常用到的寫法
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        //處理耗時操作
        
        //處理完數(shù)據(jù)回主線程
        dispatch_async(dispatch_get_main_queue(), ^{
            //回到主線程處理UI操作
        });
    });             
}
//延遲執(zhí)行
-(void)delayAction{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"延遲執(zhí)行----%@",[NSThread currentThread]);
    });
}
//某段代碼執(zhí)行一次
-(void)onceToken{
    for (int i = 0; i < 10; i++) {
        
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken,^{
            NSLog(@"某段代碼執(zhí)行一次");
        });
    }
}
//單列中GCD的應(yīng)用
+(OperationQueueViewController*)sharedOperationQueueViewController{
    static OperationQueueViewController* vc = nil;
    //加線程鎖也可以將該對象全局唯一,不會重復(fù)出現(xiàn);但是效率比較低。由于效率低,所有我們一般不使用這種方式
//    @synchronized(self) {
//        if (vc == vc) {
//            vc = [[OperationQueueViewController alloc] init];
//        }
//    }
    //官方推薦的單例的寫法
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //該block中代碼只會被執(zhí)行一次
        vc = [[OperationQueueViewController alloc] init];
    });
    return vc;
}

任務(wù)隊列

//任務(wù)隊列:任務(wù)隊列可以管理一組任務(wù),它會根據(jù)當(dāng)前的情況為任務(wù)開辟合適數(shù)量的子線程來完成任務(wù),在隊列中的任務(wù),不需要手動啟動。
//任務(wù)隊列一般分為兩種:主隊列和其它隊列。主隊列:在主隊列中的任務(wù)一定是在主線程中執(zhí)行;其它隊列:其它隊列中的任務(wù),一定是在子線程中執(zhí)行。
//主隊列
-(void)studyMainQueue{
    //創(chuàng)建主隊列對象
    NSOperationQueue* mainQueue = [NSOperationQueue mainQueue];
    NSBlockOperation* blockOperation_1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1----%@",[NSThread currentThread]);
    }];
    NSBlockOperation* blockOperation_2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"2----%@",[NSThread currentThread]);
    }];
    NSBlockOperation* blockOperation_3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"3----%@",[NSThread currentThread]);
    }];
    NSBlockOperation* blockOperation_4 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"4----%@",[NSThread currentThread]);
    }];
    NSBlockOperation* blockOperation_5 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"5----%@",[NSThread currentThread]);
    }];
    //將任務(wù)加入到隊列中,任務(wù)不用手動啟動
//    [mainQueue addOperation:blockOperation_1];
//    [mainQueue addOperation:blockOperation_2];
//    [mainQueue addOperation:blockOperation_3];
//    [mainQueue addOperation:blockOperation_4];
//    [mainQueue addOperation:blockOperation_5];
    //主隊列等待當(dāng)前所在線程操作執(zhí)行完畢之后,在執(zhí)行隊列中的任務(wù)
    //主線程在等主隊列中的任務(wù)執(zhí)行完了,在接著做其它操作
    //線程阻塞
    NSLog(@"bbbb");
    //YES:有可能會造成線程的阻塞
    //NO:主線程無需等待任務(wù)執(zhí)行完成,不會造成線程阻塞
    [mainQueue addOperations:@[blockOperation_1,blockOperation_2,blockOperation_3,blockOperation_4,blockOperation_5] waitUntilFinished:NO];
    NSLog(@"aaa");
}
//其它隊列:一定在子線程中執(zhí)行,任務(wù)是并發(fā)執(zhí)行,沒有先后順序之分
-(void)studyOttheQueue{
    //隊列對象
    NSOperationQueue* ohterQueue = [[NSOperationQueue alloc] init];
    //創(chuàng)建任務(wù)添加到隊列中
    NSBlockOperation* blockOperation_1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1----%@",[NSThread currentThread]);
    }];
    NSBlockOperation* blockOperation_2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"2----%@",[NSThread currentThread]);
    }];
    NSBlockOperation* blockOperation_3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"3----%@",[NSThread currentThread]);
    }];
    NSBlockOperation* blockOperation_4 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"4----%@",[NSThread currentThread]);
    }];
    NSBlockOperation* blockOperation_5 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"5----%@",[NSThread currentThread]);
    }];
    //如果某些任務(wù)是有先后順序的,我們可以為任務(wù)添加依賴關(guān)系
    //兩個任務(wù)不能互相為依賴,否則,兩個任務(wù)都不會執(zhí)行
//    [blockOperation_2 addDependency:blockOperation_1];
//    [blockOperation_3 addDependency:blockOperation_2];
//    [blockOperation_4 addDependency:blockOperation_3];
//    [blockOperation_5 addDependency:blockOperation_4];
    //如果想要所有的任務(wù)添加順序執(zhí)行,設(shè)置最大并大數(shù)
    [ohterQueue setMaxConcurrentOperationCount:1];
    //將任務(wù)加入到隊列中,任務(wù)不用手動啟動
    [ohterQueue addOperation:blockOperation_1];
    [ohterQueue addOperation:blockOperation_2];
    [ohterQueue addOperation:blockOperation_3];
    [ohterQueue addOperation:blockOperation_4];
    [ohterQueue addOperation:blockOperation_5];
}

NSInvocationOperation任務(wù)對象

//NSInvocationOperation 任務(wù)對象,本身和線程無關(guān),通過target—action的方法執(zhí)行一個任務(wù),需要調(diào)用start方法啟動任務(wù)。
-(void)invocationOperation{
    //初始化任務(wù)對象
    NSInvocationOperation* operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationAction:) object:@"invocation"];
    //啟動任務(wù)
    [operation start];
    
}
-(void)invocationAction:(NSString*)sender{
    NSLog(@"sender----%@",sender);
    NSLog(@"當(dāng)前線程為:%@,是否是主線程:%d",[NSThread currentThread],[NSThread isMainThread]);
}
//NSBlockOPeration.和invocationOperation基本一致,只是通過block來實現(xiàn)操作
-(void)blockOperation{
    NSBlockOperation* bOperation = [NSBlockOperation blockOperationWithBlock:^{
//        NSLog(@"");
        NSLog(@"blockOperation---%@",[NSThread currentThread]);
    }];
    //啟動任務(wù)
    [bOperation start];
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • NSThread 第一種:通過NSThread的對象方法 NSThread *thread = [[NSThrea...
    攻城獅GG閱讀 949評論 0 3
  • 在這篇文章中,我將為你整理一下 iOS 開發(fā)中幾種多線程方案,以及其使用方法和注意事項。當(dāng)然也會給出幾種多線程的案...
    張戰(zhàn)威ican閱讀 692評論 0 0
  • 進(jìn)程和線程 首先,在了解多線程之前要了解什么是進(jìn)程,什么是線程 什么是進(jìn)程呢?進(jìn)程是指在系統(tǒng)中正在運行的一個應(yīng)用程...
    擱淺的青蛙閱讀 461評論 0 0
  • 我是一個看不得有關(guān)親情故事的姑娘,因為在閑下來的每一刻我都想盡辦法要回到家人身邊,結(jié)果也總不如我所想。有時候偏就是...
    SkyVivian閱讀 258評論 0 0
  • 一直有個想法.如果我們將開發(fā)中遇到小bug的原因和解決思路分享出來.那該....我也有懶癌...1.今天分享一個:...
    侭情顯現(xiàn)閱讀 508評論 0 0

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