1.多线程理论基础
一个程序是一个独立的进程,一个进程可以同时完成多个任务。每 一个任务就是一个线程。故多线程是指同一时间处理多个任务。
本质:CPU把时间分成小片,由于同一时间,CPU只能处理一个线程。多线程就是让CPU快速的在多个线程之间进行调度,即CPU在多条的线程之间切换。CPU在每个线程调度是需要时间的,由于调度时间很小,所以给人的感觉是多个线程同时运行。eg:通常后台的算法处理与前台的显示界面分开。在iOS中,由于几乎所有UIKit提供的类都是线程不安全的,所以更新UI的操作都应该放在主线程之中。由于多线程是一个比较抽象的概念,所以如下图1.1所示是指多线程的一个款图,仅仅是在脑海中建立一个印象,方便理解。如果你看后觉得这个图不利于你的理解,可忽略。
在苹果手机中的处理器在多线程之间进行调度,PS:由于多线程是指在CPU为单核(同一时间处理1个线程)条件下,处理多个线程。所以示意图中处理器是指假设单核。调度示意图如图1.2所示:
2.优缺点
优点:1.提高程序的执行效率;
2.提高资源的利用率;
缺点:1.没开辟一条线程都会占用一定的内存空间,在官方文档中,开辟一个主线程为1MB,子线程为512KB。(仅仅是指在iOS)。
2.程序的设计复杂。eg:线程之间通信,资源共享等等。
3.IOS多线程实现方案
随着iOS技术的不断发展,整个iOS中实现多线程的方案为四个方案,分别是:
1. pthread(几乎不怎么用)
2. NSThread (一般使用查看当前线程[NSThread currentThread])
3. GCD(最为常用)
4. NSOperation
在网上看了一个图表,觉得挺好,放在这个,如下图3.1所示:
4.详解四种iOS多线程方案
4.1 pthread
pthread是一套C语言的多线程API 使用难度比较大 需要程序员手动管理线程的生命周期 能够跨平台/可移植 能够在UNIX/LINX/Windows 下运行 。在实际开发中,使用率很少,所以这里简单的介绍一下,使用方法如下:
1.第一步:包含头文件#import <pthread.h>
2.第二步:要创建线程,并开启线程执行任务
// 创建线程——定义一个pthread_t类型变量
pthread_t thread;
// 开启线程——执行任务
pthread_create(&thread, NULL, run, NULL);
void * run(void *param)
{
NSLog(@"%@", [NSThread currentThread]);
return NULL;
}
4.2 NSThread
NSThread是一套OC框架 使用更加面向对象,简单易用,可直接操作线程对象 使用次数比较少。需要程序员手动管理线程的生命周期。使用** [NSThread currentThread] **查看当前线程。返回值为 1,表示为当前线程为主线程,其他数字为子线程。
4.2.1 NSThread三种方式
.方式1:
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(test) object:nil];
[thread start];
.方式2:
[NSThread detachNewThreadSelector:@selector(test) toTarget:self withObject:nil];
.方式3:(隐式创建并启动线程)
[self performSelectorInBackground:@selector(test) withObject:nil];
4.2.2 NSThread的状态
1.新建状态
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(demo) object:nil];
2.就绪状态
[thread start];
3.阻塞状态
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
eg: [NSThread sleepForTimeInterval:3];
4.死亡状态
[NSThread exit];
线程的状态的简单代码:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//新建状态
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(demo) object:nil];
//就绪状态
[thread start];
}
- (void)demo
{
for (int i = 0; i < 10; i ++) {
if (i == 3) {
//阻塞状态
[NSThread sleepForTimeInterval:3];
}else if (i == 5)
{
//死亡状态
[NSThread exit];
}
NSLog(@"%d",i);
}
}
点击屏幕运行之后,其结果如下图4.1所示:
4.2.3 NSThread的生命周期
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(test) object:nil];
[thread start];
系统会把线程对象添加可调度线程池中,线程对象进入就绪状态。
图4.2 多线程的生命周期框图如下所示: