iOS 多线程
多线程原理:同一时间,CPU只能处理一条线程,只有一条线程在工作。多线程并发执行,其实就是CPU快速的在多线程之间调度,也就是我们所说的切换,如果切换时间过快,就造成了多线程并发执行的假象。如果线程过多,CPU会过多的被使用,CPU的资源就被大量的消耗,每条线程被调度执行的频率就会降低。
多线程优点:能够适当的提高程序的执行效率
能适当提高资源利用率(内存,CPU)
多线程的缺点:开启线程需要占用一定的内存空间(默认的情况下,主线程占1M,子线程占用512KB),如果开启大量的线程,自然就会导致大量内存空间被占用,降低了程序的性能;线程越多,CPU在调度线程上的频率也就是大了,切换线程所需的时间就会变长。大量使用多线程,大大增加了程序的复杂性,开发人员在维护代码,就会变得相对困难点儿。
多线程在开发中的应用
主线程:一个iOS程序,默认是会开启一条主线程。这条线程主要是显示/刷新UI界面,处理UI事件(点击事件,滚动事件,拖拽事件等),特别需要注意的是,不要将比较耗时的操作放在主线程执行,防止主线程堵塞,严重影响用户体验
在iOS 中创建线程通常有四种方法。
这四种方法分别是 NSObject 类方法,NSThread,NSOperation 和 NSOperationQueue组合以及 GCD.
NSObject 类方法
产生新线程。
[self performSelectorInBackground:@selector(action) withObject:nil];
在主线程中运行方法,wait表示是否阻塞这个方法的调用,如果为YES则等待主线程中运行方法结束。一般可用于在子线程中调用UI方法。
[self
performSelectorOnMainThread:@selector(action)
withObject:nil
waitUntilDone:YES];
NSThread 是一个轻量级的多线程,这是它的优点,当然它的缺点同样的明显,需要自己管理线程的生命周期,线程同步。线程同步对数据的加锁会有一定的系统开销。
NSThread 有两种创建方法
1.
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(action) object:nil]; //初始化一个子线程,需要手动开启
[thread start];//开启子线程
[thread cancel];//取消当前子线程
2.
[NSThread detachNewThreadSelector:@selector(action) toTarget:self withObject:nil];// 初始化一个子线程并自动开启
两种方法最大的区别就是,第一种需要手动开启线程,并且需要手动取消当前线程
NSOperation和NSOperationQueue 线程队列 相对于NSThread,线程队列不需要去手动管理线程的生命周期以及数据同步的事,只需要把精力放在该线程需要执行的操作
NSOperation是个抽象类,使用它必须用它的子类,可以实现它或者使用它定义好的两个子类:NSInvocationOperation 和 NSBlockOperation。
创建NSOperation子类的对象,把对象添加到NSOperationQueue队列里执行。
创建myOPeration类在.m中是在main方法中写需要子线程需要执行的代码
- (void)main
{
@autoreleasepool {
}
}
在viewController中的操作
myOperation *operation = [[myOperation alloc] init];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
最大并发数是1得时候,线程与线程是同步的,在后面为解释一下什么是同步?什么是异步?
[queue setMaxConcurrentOperationCount:1];
[queue addOperation:operation];
NSBlockOperation *blockOp = [NSBlockOperation blockOperationWithBlock:^{
@autoreleasepool {
//--->block里面的内容就是多线程所要执行的代码
}
}];
NSOperationQueue *que = [[NSOperationQueue alloc] init];
[que addOperation:blockOp];
NSInvocationOperation *invoca = [[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(calcutor) object:nil];
[que addOperation:invoca];
GCD : Grand Central Dispatch
GCD是Apple开发的一个多核编程的解决方法。在iOS4.0开始之后才能使用。GCD是一个替代诸如NSThread, NSOperationQueue, NSInvocationOperation等技术,它是高效和强大的。
创建一个同步线程:
dispatch_queue_t
queque =
dispatch_queue_create
(
"aQueue"
,
DISPATCH_QUEUE_SERIAL
);
异步执行同步线程队列:
dispatch_async(queque, ^{// ------>>把bolck里面的内容放到异步里同步执行
多线程的代码
显示到界面上,所有跟UI相关的内容全部都要在主线程运行
dispatch_async(dispatch_get_main_queue(), ^{
//回到主线程操作
});
});
//并行队列
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//DISPATCH_QUEUE_PRIORITY_DEFAULT队列执行的优先级
});
最后,简单介绍一下,同步和异步
同步:a和b排队上厕所,只有等a上完了,b才能上厕所。这就是同步,也就是说,在执行线程操作时,a线程执行完任务,b线程才执行
异步:就是a和b同时执行任务,相互不干扰,提高效率