一、基本概念编程
什么是进程: 进程是在系统运行的一个程序,每一个进程之间是独立的,每一个进程均运行在其专有且受保护的内存空间内。网络
什么是线程: 一个进程想要执行任务,必须得有线程(至少一个线程),线程是进程的基本执行单位,一个进程的全部任务都必须在线程中执行。多线程
线程的串行: 一个线程中任务的执行是串行的,若是要在一个线程中执行多个任务,只能一个一个的按顺序执行并发
二、多线程框架
什么是多线程:性能
一个进程中能够开启多个线程,每一个线程能够并发/并行执行不一样的任务,多线程能够提交程序的执行效率,好比同时执行任务ABC。线程
多线程原理:调试
同一时间,CPU只能执行一个线程,只有一个线程正在执行,多线程并发执行,实际上是CPU快速的在多个线程之间切换,若是CPU的切换线程的时间足够快,就会形成多线程并发执行的假象。code
多线程的优缺点:orm
优势: 1.能适当的提升程序的执行效率 2.能适当的提升资源的利用率 缺点: 1.开启线程会占用必定的内存空间(主线程1M,子线程0.5M),若是开启过多的线程就会占用大量的内存空间,下降程序的性能。 2.线程越多,CPU在调度线程上的开销就越大。
三、主线程
一个IOS程序运行之后,默认会开启一个线程,这个线程就被称为主线程或(UI线程)。主线程的主要做用是显示/刷新UI界面,处理UI事件(点击,滚动,拖拽等)。
IOS中的多线程:
iOS中有四种多线程编程的技术:
1.Pthread (基本不会使用,线程的生命周期由咱们⾃己管理)
2.NSThread(每一个Thread对象对应⼀一个线程)(使⽤用得⽐比较少,线程的⽣生命周期由咱们⾃己管理)
3.NSOperation(面向对象的线程技术)(基于gcd来实现,常常使⽤,⽣命周期由系统管理)
4.GCD(是基于C语⾔言的框架,能够充分利用多核,是苹果推荐使⽤的多线程技术)(常常使用,生命周期由系统管理))
以上这四种编程⽅方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单,也是Apple最推荐使用的。可是就目前而言,iOS的开发者,须要了解三种多线程技术的基本使⽤用过程。由于不少 框架技术分别使用了不一样多线程技术。 代码示例,用多线程加载图片: 1、NSThread
#pragma 建立多个线程 -(void)loadImageViewWithThread{ //建立多个线程 9个图片 for (int i=0; i<9; i++) { NSThread *thread=[[NSThread alloc]initWithTarget:self selector:@selector(myThread2:) object:[NSNumber numberWithInt:i]]; //线程的优先级只是提升优先被加载的概率,可是它未必是第一个加载 //网络情况的制约 if(i==8){ thread.threadPriority=1; }else{ thread.threadPriority=0; } //能够给线程一个名称,方便调试、调用 thread.name=[NSString stringWithFormat:@"线程:%d",i]; //开始执行 [thread start]; } } #pragma 子线程,带参数 -(void)myThread2:(NSNumber*)index{ //当不是最后一个线程时 if(![index isEqual:@8]){ //线程休眠2秒 [NSThread sleepForTimeInterval:2]; } //打印当前线程的名称 NSLog(@"当前线程:%@",[NSThread currentThread].name); NSData*data=[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://a.hiphotos.baidu.com/zhidao/pic/item/e7cd7b899e510fb3bf607192da33c895d1430cbd.jpg"]]]; NSArray*array=@[data ,index]; [self performSelectorOnMainThread:@selector(upData:) withObject:array waitUntilDone:YES]; } #pragma 回归主线程 -(void)upData:(NSArray*)sender{ int index=[sender[1] intValue]; UIImageView *imageView=_imageViews[index]; imageView.image=[UIImage imageWithData:sender[0]]; }
2、NSOperation
#pragma NSOperation 开启多线程 -(void)loadImageViewWithOperation{ //1.建立一个操做队列(没有顺序) NSOperationQueue *opereatioQueue=[[NSOperationQueue alloc]init]; //设置最大并发线程数 opereatioQueue.maxConcurrentOperationCount=2; // //2.向队列添加操做 // for (int i=0; i<15; i++) { // //方法1.建立操做快,添加到对列 //// NSBlockOperation*blockOperatio=[NSBlockOperation blockOperationWithBlock:^{ //// [self loadImageWith:i]; //// }]; //// [opereatioQueue addOperation:blockOperatio]; // //方法2.祷文invocation // NSInvocationOperation*invocationOperatio=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(loadImages:) object:[NSNumber numberWithInt:i]]; // [opereatioQueue addOperation:invocationOperatio]; //} //方法3.控制线程的执行顺序,创建依赖操做关系 NSMutableArray *arr=[NSMutableArray array]; for (int i=0; i<_imageViews.count; i++) { //建立全部操做 NSBlockOperation*op1=[NSBlockOperation blockOperationWithBlock:^{ [self loadImages:[NSNumber numberWithInt:i]]; }]; [arr addObject:op1]; } for (int i=0; i<arr.count-1; i++) { //对操做进行依赖设置(后一个依赖前一个) [arr[i+1] addDependency:arr[i]]; } for (int i=0; i<arr.count; i++) { //把操做加入到队列中 [opereatioQueue addOperation:arr[i]]; } } #pragma 代码块回调方法 -(void)loadImage:(int)index{ if(index==7){ NSData*data=[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://img.kejik.com/20151017/1445089621639.jpg"]]]; UIImageView*imageView=_imageViews[index]; imageView.image=[UIImage imageWithData:data]; }else{ NSData*data=[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://img.taopic.com/uploads/allimg/120505/154405-1205051U41588.jpg"]]]; UIImageView*imageView=_imageViews[index]; imageView.image=[UIImage imageWithData:data]; } } -(void)loadImageWith:(int )index{ NSData*data; if(index==7){ data=[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://img2.niutuku.com/desk/1207/1101/bizhi-1101-55018.jpg"]]]; }else{ data=[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://img.taopic.com/uploads/allimg/120505/154405-1205051U41588.jpg"]]]; } //回归主线程,更新UI [[NSOperationQueue mainQueue]addOperationWithBlock:^{ //主线程 UIImageView *imageView=_imageViews[index]; imageView.image=[UIImage imageWithData:data]; }]; } #pragma 祷文,子线程方法 -(void)loadImages:(NSNumber*)sender{ int index=[sender intValue]; NSData*data; if(index==7){ data=[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://www.ld12.com/upimg358/20160130/00230293571003.jpg"]]]; }else{ data=[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://img.taopic.com/uploads/allimg/120505/154405-1205051U41588.jpg"]]]; } //回归主线程,更新UI [[NSOperationQueue mainQueue]addOperationWithBlock:^{ //主线程 UIImageView *imageView=_imageViews[index]; imageView.image=[UIImage imageWithData:data]; }]; NSLog(@"%@",sender); }