谈iOS多线程(NSThread、NSOperation、GCD)编程

一.基本概念

计算机操作系统都有的基本概念,以下概念简单方式来描述。

进程: 一个具有一定独立功能的程序关于某个数据集合的一次运行活动。可以理解成一个运行中的应用程序。

线程: 程序执行流的最小单元,线程是进程中的一个实体。

同步: 只能在当前线程按先后顺序依次执行,不开启新线程。

异步: 可以在当前线程开启多个新线程执行,可不按顺序执行。

队列: 装载线程任务的队形结构。

并发: 线程执行可以同时一起进行执行。

串行: 线程执行只能依次逐一先后有序的执行。

注意:

一个进程可有多个线程。

一个进程可有多个队列。

队列可分并发队列和串行队列。

二.iOS多线程对比

1. NSThread

每个NSThread对象对应一个线程,真正最原始的线程。

1)优点:NSThread 轻量级最低,相对简单。

2)缺点:手动管理所有的线程活动,如生命周期、线程同步、睡眠等。

2. NSOperation

自带线程管理的抽象类。

1)优点:自带线程周期管理,操作上可更注重自己逻辑。

2)缺点:面向对象的抽象类,只能实现它或者使用它定义好的两个子类:NSInvocationOperation 和 NSBlockOperation。

3. GCD

Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法。

1)优点:最高效,避开并发陷阱。

2)缺点:基于C实现。

5. 选择小结

1)简单而安全的选择NSOperation实现多线程即可。

2)处理大量并发数据,又追求性能效率的选择GCD。

3)NSThread本人选择基本上是在做些小测试上使用,当然也可以基于此造个轮子。

三.场景选择

图片异步加载。这种常见的场景是最常见也是必不可少的。异步加载图片有分成两种来说明一下。

第一种,在UI主线程开启新线程按顺序加载图片,加载完成刷新UI。

第二种,依然是在主线程开启新线程,顺序不定地加载图片,加载完成个字刷新UI。

创作工具上的异步。 这个跟上边任务调度道理,只是为了丰富描述,有助于“举一反三”效果。如下描述的是app创作小说。

场景一,app本地创作10个章节内容未成同步服务器,同时发表这10个章节产生的一系列动作,其中上传内容,获取分配章节Id,如何后台没有做处理最好方式做异步按顺序执行。

场景二,app本地创作列表中有3本小说为发表,同时发表创作列表中的3本小说,自然考虑并行队列执行发表。

四.使用方法

第三标题场景选择内容实现先留下一个悬念。具体实现还是先熟知一下各自的API先。

1. NSThread

1.1)三种实现开启线程方式:

①.动态实例化

NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(loadImageSource:) object:imgUrl];

thread.threadPriority = 1;// 设置线程的优先级(0.0 - 1.0,1.0最高级)

[thread start];

②.静态实例化

[NSThread detachNewThreadSelector:@selector(loadImageSource:) toTarget:self withObject:imgUrl];

③.隐式实例化

[self performSelectorInBackground:@selector(loadImageSource:) withObject:imgUrl];

有了以上的知识点,可以试探了一下编写场景选择中的“图片加载”的基本功能了。

1.2)使用这三种方式编写代码

//动态创建线程

-(void)dynamicCreateThread{

NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(loadImageSource:) object:imgUrl];

thread.threadPriority = 1;// 设置线程的优先级(0.0 - 1.0,1.0最高级)

[thread start];

}

//静态创建线程

-(void)staticCreateThread{

[NSThread detachNewThreadSelector:@selector(loadImageSource:) toTarget:self withObject:imgUrl];

}

//隐式创建线程

-(void)implicitCreateThread{

[self performSelectorInBackground:@selector(loadImageSource:) withObject:imgUrl];

}

-(void)loadImageSource:(NSString *)url{

NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];

UIImage *image = [UIImage imageWithData:imgData];

if (imgData!=nil) {

[self performSelectorOnMainThread:@selector(refreshImageView:) withObject:image waitUntilDone:YES];

}else{

NSLog(@"there no image data");

}

}

-(void)refreshImageView:(UIImage *)image{

[self.imageView setImage:image];

}

你可能感兴趣的:(谈iOS多线程(NSThread、NSOperation、GCD)编程)