一、基本概念:
进程:一个具有一定独立功能的程序关于某个数据集合的一次运行活动,可以理解成一个运行中的应用程序
线程:程序执行的最小单元,线程是进程中的而一个实体
主线程:一个ios程序运行后,默认会开启一条线程,成为“主线程”,主线程的作用是:显示/刷新UI界面 处理UI时间(如:点击事件、滚动事件、拖拽事件)
二、iOS多线程对比
1、NSThread 每个NSThread对线对应一个线程,真正最原始的线程。优点:NSThread轻量级最低,相对简单。 缺点:手动管理所有的线程活动,如生命周期、线程同步、睡眠等。
2、NSOperation 自带线程管理的抽象类 优点:自带线程周期管理,操作上可更注重自己的逻辑,可以添加操作任务之间的依赖关系。缺点:面向对象的抽象类,只能实现它或者使用它定义好的两个子类,NSInvocationOperation和NSBlockOperation。
3、GCD 是apple开发的一个多核编程的解决方法 优点:充分利用CPU的多核,自动管理线程的生命周期,最高效,避开并发陷阱。 缺点:基于C实现
总结:简单而安全的选择NSOperation实现多线程即可,处理大量并发数据,又追求性能效率的选择GCD
三、多线程的使用方法
加锁方法1;
@synchornized(self){ }
方法2: @property (nonatomic, retain)NSLock * lock;
加锁 [_lock lock] 解锁[_lock unlock];
打印当前线程是不是主线程
NSLog(@“%@—%d”,[NSThread currentThread],[[NSThread currentThread]isMainThread]);
在后台执行
[self performSelectorInBackground:@selector( ) withObject: nil];
NSThread 是一个轻量级的多线程,有两种创建方法。
1. init 方法需要手动开启和关闭
NSThread * thread = [[NSThread alloc] initWithTarget:self selector:@selector( ) object:nil];
开启线程 【thread start】 取消线程【thread cancel】
2.初始化的同时 开启子线程(背)
【NSThread detachNewThreadSelector:@selector()toTarget:self withObject:nil】;
NSOperation是一个抽象的类,他有两个子类,在MVC里属于M层,用来封装单个任务的数据和相关代码的抽象类,一般我们使用子类‘
1.NSInvocationOperation只是一个操作,本身并无主线程、子线程的区别,通常与NSOperationQueue结合使用
2.NSBlockOperation
NSOperationQueue是线程操作队列,用来管理一组operation对象,会根据实际需求创建出适合数量的子线程,完成任务的并发执行
GCD三种队列 1.主队列 2.全局队列 3.自定义队列
FIFO:先进先出。
1.获取主队列:(获取一个主队列生成一个串行的队列,队列里的block块按照FIFO的顺序执行,实际上就是一个单线程队列)
dispatch_queue_t mainQueue = dispatch_get_main_queue();
1.2向队列里添加任务
__weak typeof (self)temp = self;
dispatch_async(mainQueue, ^{
[temp test]; })
延时队列 (延时5秒)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (5 * NSEC_PER_SEC)),dispatch_get_main_queue(), ^{ });
2.全局队列 (并发执行,没有主线程和子线程之分)
dispatch_queue_t global = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
添加任务的方法与 1 一样 需要__weak;
2.1重复执行:第一个参数是执行重复的次数,第二个参数是指定执行队列(第二个参数不能是mainQueue)
dispatch_apply(5, global, ^(size_t t) { });
主队列是串行队列,全局队列是并行队列,而且他们都是单例。
3.自定义队列
第一个参数是该队的名称,第二个参数:该队列的类型(例子是 串行队列)
dispatch_queue_t queue1 = dispatch_queue_create(“aaa”,DISPATCH_QUEUE_SERIAL);
添加函数
dispatch_async_f(queue1, “context”,function);
并行
dispatch_queue_t queue2 = dispatch_queue_create(“bbb”,DISPATCH_QUEUE_CONCURRNET);
分组任务
dispatch_queue_t group1 = dispatch_group_create() ;
放在结尾的语句
dispatch_group_notify(group1,queue2, ^{ });
子线程回归主线程
1.dispatch_async(dispatch_get_main_queue(),^ { });
2. [self performSelectorOnMainThread:@selector(load) withObject:nil waitUntilDone:Yes];