美文网首页程序员
iOS多线程概述

iOS多线程概述

作者: One苹果OneDay | 来源:发表于2016-07-21 22:02 被阅读93次

1.多线程的简单认知

1.进程和线程的认知

进程:一个正在运行的程序就是一个进程 一个进程由一个或多个线程组成进程只负责资源的调度分配,线程才是真正的执行单元

线程

//当我们应用程序刚刚运行的时候,系统会自动为我们开放一个线程,这个线程叫做主线程

//子线程:程序员用代码手动开启的线程

//子线程存在的意义:执行耗时操作的任务

//子线程在执行完自己的任务之后会自动销毁

2.创建线程

第一种

-(void)createNSThread

{

//创建一个线程###

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

{

//快捷创建 无返回值

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

}

第三种

-(void)createNSThread2

{

//隐式开启线程

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

}

2.NSOperation

/NSOperation 是一个抽象类,我们一般不直接使用它,而是使用它的子类NSInvocationOperation 类 还有NSBlockOperation

//如果他们单独使用都是在主线程执行,只有和队列放在一起才是在子线程下执行的

-(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);

}}];

//操作队列

//目的:是将我们的任务放在一个队列中执行

//任务:任务执行在主线程还是在子线程全都是由我们的队列来决定的

//加入到队列

//mainQueue 代表主队列

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

//  NSOperationQueue *queue = [NSOperationQueue mainQueue];

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

//先加的先执行,后加的后执行,但执行的时间不一定 可能后边的现执行完

[queue addOperation:operation1];

[queue addOperation:operation2];

[queue addOperation:operation3];

}

-(void)operationAction2

{

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

}

-(void)operationAction1

{

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

}

3.GCD

在了解GCD之前我们应该先了解几个基础概念

异步:不再一个线程执行

同步:在同一个线程执行

串行:按顺序串在一起执行

并行:一起执行

#pragma --------- 同步主队列 ------------

//同步不能加主队列 所以这个是错的,仅仅是看个模式

-(void)createScyMain

{

//获得主队列(主队列也是一个串行队列)

dispatch_queue_t queue = dispatch_get_main_queue();

//将任务加到队列中

//第一个参数:放队列的

//第二个参数:要执行的任务

dispatch_sync(queue, ^{

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

});

dispatch_sync(queue, ^{

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

});

dispatch_sync(queue, ^{

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

});

}

#pragma --------- 异步主队列 ------------

//不开辟线程,就在主线程执行

-(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

{

//创建串行队列

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

{

//创建一个并发队列

//第一个参数 队列的名字

//第二个参数 类型

//我们自己创建的并发队列

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

//获得全局的并发队列

//第一个参数是优先级,默认的就行了

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 --------- 异步并行队列 ------------

//最经常使用的就是这个

//异步具备开启子线程的能力,并且并行执行任务

-(void)createAsynConcurrent

{

//获得全局的并发队列

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.

//创建全局的并发队列

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函数的使用

延时执行

-(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);

//创建一个组队列

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;

});

});

}

相关文章

网友评论

    本文标题:iOS多线程概述

    本文链接:https://www.haomeiwen.com/subject/vgwbjttx.html