iOS多線程概述

1.多線程的簡單認知

1.進程和線程的認知

進程:一個正在運行的程序就是一個進程 一個進程由一個或多個線程組成進程只負責資源的調度分配,線程才是真正的執(zhí)行單元

線程

//當我們應用程序剛剛運行的時候,系統(tǒng)會自動為我們開放一個線程,這個線程叫做主線程

//子線程:程序員用代碼手動開啟的線程

//子線程存在的意義:執(zhí)行耗時操作的任務

//子線程在執(zhí)行完自己的任務之后會自動銷毀

2.創(chuàng)建線程

第一種

-(void)createNSThread

{

//創(chuàng)建一個線程###

NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(haoshicaozuo) object:@"123"];

thread.name = @"這是一個線程";

[thread start];

//NSLog(@"%@",thread);

NSLog(@"%@",[NSThread mainThread]);//打印當前應用程序的主線程

NSLog(@"%@",[NSThread currentThread]);//當前線程

NSLog(@"%d",[NSThread isMainThread]); //判斷是否為主線程

}

第二種

-(void)createNSThread1

{

//快捷創(chuàng)建 無返回值

[NSThread detachNewThreadSelector:@selector(haoshicaozuo) toTarget:self withObject:@"456"];

}

第三種

-(void)createNSThread2

{

//隱式開啟線程

[NSThread cancelPreviousPerformRequestsWithTarget:self selector:@selector(haoshicaozuo) object:@"789"];

}

2.NSOperation

/NSOperation 是一個抽象類,我們一般不直接使用它,而是使用它的子類NSInvocationOperation 類 還有NSBlockOperation

//如果他們單獨使用都是在主線程執(zhí)行,只有和隊列放在一起才是在子線程下執(zhí)行的

-(void)createNSOperation

{

NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationAction1) object:nil];

//[operation1 start];

NSInvocationOperation *operation2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationAction2) object:

nil];

NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{

for (int i = 20 ; i < 30 ; i++)? {

NSLog(@"%d",i);

}}];

//操作隊列

//目的:是將我們的任務放在一個隊列中執(zhí)行

//任務:任務執(zhí)行在主線程還是在子線程全都是由我們的隊列來決定的

//加入到隊列

//mainQueue 代表主隊列

//如果 alloc init 的就代表其他隊列

//? NSOperationQueue *queue = [NSOperationQueue mainQueue];

NSOperationQueue *queue = [[NSOperationQueue alloc] init] ;

//先加的先執(zhí)行,后加的后執(zhí)行,但執(zhí)行的時間不一定 可能后邊的現(xiàn)執(zhí)行完

[queue addOperation:operation1];

[queue addOperation:operation2];

[queue addOperation:operation3];

}

-(void)operationAction2

{

NSLog(@"%d",[NSThread isMainThread]);

}

-(void)operationAction1

{

NSLog(@"%d",[NSThread isMainThread]);

}

3.GCD

在了解GCD之前我們應該先了解幾個基礎概念

異步:不再一個線程執(zhí)行

同步:在同一個線程執(zhí)行

串行:按順序串在一起執(zhí)行

并行:一起執(zhí)行

#pragma --------- 同步主隊列 ------------

//同步不能加主隊列 所以這個是錯的,僅僅是看個模式

-(void)createScyMain

{

//獲得主隊列(主隊列也是一個串行隊列)

dispatch_queue_t queue = dispatch_get_main_queue();

//將任務加到隊列中

//第一個參數(shù):放隊列的

//第二個參數(shù):要執(zhí)行的任務

dispatch_sync(queue, ^{

NSLog(@"1.......%@",[NSThread currentThread]);

});

dispatch_sync(queue, ^{

NSLog(@"2.......%@",[NSThread currentThread]);

});

dispatch_sync(queue, ^{

NSLog(@"3.......%@",[NSThread currentThread]);

});

}

#pragma --------- 異步主隊列 ------------

//不開辟線程,就在主線程執(zhí)行

-(void)createAsycnMain

{

//獲得主隊列(主隊列也是一個串行隊列)

dispatch_queue_t queue = dispatch_get_main_queue();

dispatch_async(queue, ^{

NSLog(@"1..........%@",[NSThread currentThread]);

});

dispatch_async(queue, ^{

NSLog(@"2..........%@",[NSThread currentThread]);

});

dispatch_async(queue, ^{

NSLog(@"3..........%@",[NSThread currentThread]);

});

}

#pragma --------- 同步串行隊列 ------------

//不具備開啟線程的能力,在當前線程完成任務

-(void)createSyncSerial

{

//創(chuàng)建串行隊列

dispatch_queue_t queue = dispatch_queue_create("aaa.com", DISPATCH_QUEUE_SERIAL);

dispatch_sync(queue, ^{

NSLog(@"1........%@",[NSThread currentThread]);

});

dispatch_sync(queue, ^{

NSLog(@"2........%@",[NSThread currentThread]);

});

dispatch_sync(queue, ^{

NSLog(@"3........%@",[NSThread currentThread]);

});

}

#pragma --------- 異步串行隊列 ------------

//具備開啟線程的能力,但是任務是串行的

-(void)createAsyncSerial

{

dispatch_queue_t queue = dispatch_queue_create("aaa.com", DISPATCH_QUEUE_SERIAL);

dispatch_async(queue, ^{

NSLog(@"1........%@",[NSThread currentThread]);

});

dispatch_async(queue, ^{

NSLog(@"2.......%@",[NSThread currentThread]);

});

dispatch_async(queue, ^{

NSLog(@"3........%@",[NSThread currentThread]);

});

}

#pragma --------- 同步并行隊列 ------------

//不具備開啟線程的能力,其實同步的都在主線程,主線程沒有串行隊列 ,所以并行的功能就沒有用了

-(void)createSyncConcurrent

{

//創(chuàng)建一個并發(fā)隊列

//第一個參數(shù) 隊列的名字

//第二個參數(shù) 類型

//我們自己創(chuàng)建的并發(fā)隊列

// dispatch_queue_t queue = dispatch_queue_create("sb.com", DISPATCH_QUEUE_CONCURRENT);

//獲得全局的并發(fā)隊列

//第一個參數(shù)是優(yōu)先級,默認的就行了

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_sync(queue, ^{

NSLog(@"1.........%@",[NSThread currentThread]);

});

dispatch_sync(queue, ^{

NSLog(@"2.........%@",[NSThread currentThread]);

});

dispatch_sync(queue, ^{

NSLog(@"3.........%@",[NSThread currentThread]);

});

}

#pragma --------- 異步并行隊列 ------------

//最經常使用的就是這個

//異步具備開啟子線程的能力,并且并行執(zhí)行任務

-(void)createAsynConcurrent

{

//獲得全局的并發(fā)隊列

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(queue, ^{

NSLog(@"1.......%@",[NSThread currentThread]);

});

dispatch_async(queue, ^{

NSLog(@"2.......%@",[NSThread currentThread]);

});

dispatch_async(queue, ^{

NSLog(@"3.......%@",[NSThread currentThread]);

});

NSLog(@"大傻逼");

}

4-GCD網絡請求的應用

以請求一張圖片為例我們在ViewController的viewDidLoad里面要寫上如下代碼

- (void)viewDidLoad {

[super viewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

//創(chuàng)建全局的并發(fā)隊列

dispatch_queue_t? queue = dispatch_queue_create("aaa", DISPATCH_QUEUE_CONCURRENT);

dispatch_async(queue, ^{

NSURL *url = [NSURL URLWithString: @"https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1464140268&di=6b6b2e3ea5da34b7da1e02fd28c7acd2&src=http://pic36.nipic.com/20131115/12106414_153522431000_2.jpg"];

NSData *data = [NSData dataWithContentsOfURL:url];

dispatch_async(dispatch_get_main_queue(), ^{

//UI層的東西只有回到主線程里才能設置

self.imgView.image? = [UIImage imageWithData:data];

});

});

}

5-GCD函數(shù)的使用

延時執(zhí)行

-(void)creatAfter

{

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

NSLog(@"%@",[NSThread currentThread]);

NSLog(@"皮卡皮卡,皮卡丘");

});

}

快速遍歷

-(void)rapidTeaverse

{

for (int i = 0; i < 10; i++) {

NSLog(@"%d",i);

}

dispatch_queue_t queue =? dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_apply(10, queue, ^(size_t index) {

NSLog(@"%zd %@",index,[NSThread currentThread]);

});

}

組隊列

-(void)creatGroup

{

//獲取并行隊列

dispatch_queue_t queue =? dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//創(chuàng)建一個組隊列

dispatch_group_t group = dispatch_group_create();

//下載圖片1

dispatch_group_async(group, queue, ^{

NSURL *url = [NSURL URLWithString:@"https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1464231860&di=33256b2f206f8082ad634b5250a2b39d&src=http://www.benbenla.cn/images/20120330/benbenla-04b.jpg"];

NSData *data = [NSData dataWithContentsOfURL:url];

self.image1 = [UIImage imageWithData:data];

});

dispatch_group_async(group, queue, ^{

NSURL *url = [NSURL URLWithString:@"http://www.deskcar.com/desktop/fengjing/200895150214/21.jpg"];

NSData *data = [NSData dataWithContentsOfURL:url];

self.image2 = [UIImage imageWithData:data];

});

//將圖片1和2組合在一起

dispatch_group_notify(group, queue, ^{

//開啟一個新的圖片上下文

UIGraphicsBeginImageContext(CGSizeMake(375, 667));

//繪制圖片

[self.image1 drawInRect:CGRectMake(0, 0, 375/2, 667)];

[self.image2 drawInRect:CGRectMake(375/2, 0, 375/2, 667)];

//取得圖片上下文中的圖片

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

//結束圖片上下文

UIGraphicsEndImageContext();

dispatch_async(dispatch_get_main_queue(), ^{

self.imgV.image = image;

});

});

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • NSThread 第一種:通過NSThread的對象方法 NSThread *thread = [[NSThrea...
    攻城獅GG閱讀 952評論 0 3
  • 在這篇文章中,我將為你整理一下 iOS 開發(fā)中幾種多線程方案,以及其使用方法和注意事項。當然也會給出幾種多線程的案...
    張戰(zhàn)威ican閱讀 698評論 0 0
  • 一、前言 上一篇文章iOS多線程淺匯-原理篇中整理了一些有關多線程的基本概念。本篇博文介紹的是iOS中常用的幾個多...
    nuclear閱讀 2,144評論 6 18
  • 陸玖是一張木床。 它不同于世上任何一張木床。 它有思想有床格。 能夠像人一樣思考的陸玖為什么成了一張床呢? 這就是...
    啊小美閱讀 786評論 0 5

友情鏈接更多精彩內容