1.多線程的簡(jiǎn)單認(rèn)知
1.進(jìn)程和線程的認(rèn)知
進(jìn)程:一個(gè)正在運(yùn)行的程序就是一個(gè)進(jìn)程 一個(gè)進(jìn)程由一個(gè)或多個(gè)線程組成進(jìn)程只負(fù)責(zé)資源的調(diào)度分配删豺,線程才是真正的執(zhí)行單元
線程
//當(dāng)我們應(yīng)用程序剛剛運(yùn)行的時(shí)候,系統(tǒng)會(huì)自動(dòng)為我們開放一個(gè)線程吼鳞,這個(gè)線程叫做主線程
//子線程:程序員用代碼手動(dòng)開啟的線程
//子線程存在的意義:執(zhí)行耗時(shí)操作的任務(wù)
//子線程在執(zhí)行完自己的任務(wù)之后會(huì)自動(dòng)銷毀
2.創(chuàng)建線程
第一種
-(void)createNSThread
{
//創(chuàng)建一個(gè)線程###
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(haoshicaozuo) object:@"123"];
thread.name = @"這是一個(gè)線程";
[thread start];
//NSLog(@"%@",thread);
NSLog(@"%@",[NSThread mainThread]);//打印當(dāng)前應(yīng)用程序的主線程
NSLog(@"%@",[NSThread currentThread]);//當(dāng)前線程
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 是一個(gè)抽象類,我們一般不直接使用它赔桌,而是使用它的子類NSInvocationOperation 類 還有NSBlockOperation
//如果他們單獨(dú)使用都是在主線程執(zhí)行,只有和隊(duì)列放在一起才是在子線程下執(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);
}}];
//操作隊(duì)列
//目的:是將我們的任務(wù)放在一個(gè)隊(duì)列中執(zhí)行
//任務(wù):任務(wù)執(zhí)行在主線程還是在子線程全都是由我們的隊(duì)列來決定的
//加入到隊(duì)列
//mainQueue 代表主隊(duì)列
//如果 alloc init 的就代表其他隊(duì)列
//? NSOperationQueue *queue = [NSOperationQueue mainQueue];
NSOperationQueue *queue = [[NSOperationQueue alloc] init] ;
//先加的先執(zhí)行音诫,后加的后執(zhí)行,但執(zhí)行的時(shí)間不一定 可能后邊的現(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之前我們應(yīng)該先了解幾個(gè)基礎(chǔ)概念
異步:不再一個(gè)線程執(zhí)行
同步:在同一個(gè)線程執(zhí)行
串行:按順序串在一起執(zhí)行
并行:一起執(zhí)行
#pragma --------- 同步主隊(duì)列 ------------
//同步不能加主隊(duì)列 所以這個(gè)是錯(cuò)的竭钝,僅僅是看個(gè)模式
-(void)createScyMain
{
//獲得主隊(duì)列(主隊(duì)列也是一個(gè)串行隊(duì)列)
dispatch_queue_t queue = dispatch_get_main_queue();
//將任務(wù)加到隊(duì)列中
//第一個(gè)參數(shù):放隊(duì)列的
//第二個(gè)參數(shù):要執(zhí)行的任務(wù)
dispatch_sync(queue, ^{
NSLog(@"1.......%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"2.......%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3.......%@",[NSThread currentThread]);
});
}
#pragma --------- 異步主隊(duì)列 ------------
//不開辟線程,就在主線程執(zhí)行
-(void)createAsycnMain
{
//獲得主隊(duì)列(主隊(duì)列也是一個(gè)串行隊(duì)列)
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 --------- 同步串行隊(duì)列 ------------
//不具備開啟線程的能力香罐,在當(dāng)前線程完成任務(wù)
-(void)createSyncSerial
{
//創(chuàng)建串行隊(duì)列
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 --------- 異步串行隊(duì)列 ------------
//具備開啟線程的能力时肿,但是任務(wù)是串行的
-(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 --------- 同步并行隊(duì)列 ------------
//不具備開啟線程的能力庇茫,其實(shí)同步的都在主線程螃成,主線程沒有串行隊(duì)列 ,所以并行的功能就沒有用了
-(void)createSyncConcurrent
{
//創(chuàng)建一個(gè)并發(fā)隊(duì)列
//第一個(gè)參數(shù) 隊(duì)列的名字
//第二個(gè)參數(shù) 類型
//我們自己創(chuàng)建的并發(fā)隊(duì)列
// dispatch_queue_t queue = dispatch_queue_create("sb.com", DISPATCH_QUEUE_CONCURRENT);
//獲得全局的并發(fā)隊(duì)列
//第一個(gè)參數(shù)是優(yōu)先級(jí)寸宏,默認(rèn)的就行了
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 --------- 異步并行隊(duì)列 ------------
//最經(jīng)常使用的就是這個(gè)
//異步具備開啟子線程的能力,并且并行執(zhí)行任務(wù)
-(void)createAsynConcurrent
{
//獲得全局的并發(fā)隊(duì)列
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網(wǎng)絡(luò)請(qǐng)求的應(yīng)用
以請(qǐng)求一張圖片為例我們?cè)赩iewController的viewDidLoad里面要寫上如下代碼
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//創(chuàng)建全局的并發(fā)隊(duì)列
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層的東西只有回到主線程里才能設(shè)置
self.imgView.image? = [UIImage imageWithData:data];
});
});
}
5-GCD函數(shù)的使用
延時(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]);
});
}
組隊(duì)列
-(void)creatGroup
{
//獲取并行隊(duì)列
dispatch_queue_t queue =? dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//創(chuàng)建一個(gè)組隊(duì)列
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, ^{
//開啟一個(gè)新的圖片上下文
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();
//結(jié)束圖片上下文
UIGraphicsEndImageContext();
dispatch_async(dispatch_get_main_queue(), ^{
self.imgV.image = image;
});
});
}