ios:多线程

来源:互联网 发布:富途网络怎么样 编辑:程序博客网 时间:2024/04/29 13:46

今天我们讲解ios里三种跟多线程有联系的东西,分别是GCD、NSOpreration、NSThread。

一.GCD

介绍:

Grand Central Dispatch 简称(GCD)是苹果公司开发的技术,以优化的应用程序支持多核心处理器和其他的对称多处理系统的系统。这建立在任务并行执行的线程池模式的基础上的。它首次发布在Mac OS X 10.6 ,iOS 4及以上也可用。

GCD的工作原理是:让程序平行排队的特定任务,根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务。

一个任务可以是一个函数(function)或者是一个block。 GCD的底层依然是用线程实现,不过这样可以让程序员不用关注实现的细节。

GCD中的FIFO队列称为dispatch queue,它可以保证先进来的任务先得到执行


 NSLog(@"主线程: %@",[NSThread mainThread]);   //获取系统提供的全局串行队列(主队列)    //在同步线程下获取主队列会卡死 所以 如果使用同步线程,则不要使用系统的全局主队列(串行)//    dispatch_queue_t queue = dispatch_get_main_queue();    //    //创建一个同步线程 第一个参数:队列名字;第二个参数:要执行的任务//    dispatch_sync(queue, ^{//        NSLog(@"当前线程:%@",[NSThread currentThread]);//    });        //开启一个异步线程,并向队列添加一项任务    //异步状态下的串行队列 所有的任务都会在同一个线程下执行        //创建一个串行队列    //第一个参数:队列的名字    //第二个参数:创建队列的宏        //同步下的自定义串行队列:还是在主线程里面做事情    //异步下的自定义串行队列:会开辟一条线程,去做事情//    dispatch_queue_t queue = dispatch_queue_create("q1", DISPATCH_QUEUE_SERIAL);        //获取系统的全局 并发队列    //DISPATCH_QUEUE_PRIORITY_BACKGROUND 获取系统提供的并发队列,分为四个优先级,优先级在资源充足的情况下没有意义,在系统资源不充足的情况下会优先执行优先级高的线程    //并发状态下的同步:永远不会开辟新的子线程,只会在主线程内操作    //并发状态下的异步:每一个任务都会单独开辟的一个子线程    // dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);        //异步状态下的串行 == 当前线程内的同步执行    //创建一个并发队列    dispatch_queue_t queue = dispatch_queue_create("q2", DISPATCH_QUEUE_CONCURRENT);    //异步    dispatch_async(queue, ^{        NSLog(@"当前线程1:%@",[NSThread currentThread]);    });    dispatch_async(queue, ^{        NSLog(@"当前线程2:%@",[NSThread currentThread]);    });    dispatch_async(queue, ^{        NSLog(@"当前线程3:%@",[NSThread currentThread]);    });    //同步    dispatch_sync(queue, ^{        NSLog(@"当前线程1(同步):%@",[NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"当前线程2(同步):%@",[NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"当前线程3(同步):%@",[NSThread currentThread]);    });    //GCD提供的一些额外的功能    //线程锁    //经常在单例中使用    //设置blockn块里面的代码 同一时间只有一个线程可以访问    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{            });        //代表的是  多久之后  执行代码块里面的任务    //就一个需要填写的,就是时间    //本质上,是让线程休眠一会儿    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{            });        //重复的做代码块里面的事情    //第一个参数:代表的是执行多少次    //在某个线程内做这件事    //block需要填写一个参数 参数的意义是执行到第几次了    //基本上相当于一个for循环dispatch_apply(10, dispatch_get_main_queue(), ^(size_t){    });        //NSObject 常用的两个方法    //几秒之后 去SEL 里面执行里面的代码//    self performSelector:<#(SEL)#> withObject:<#(id)#> afterDelay:<#(NSTimeInterval)#>    //创建一个低优先级的子线程//    self performSelectorInBackground:<#(SEL)#> withObject:<#(id)#>    //返回主线程去做SEL里面的事情 最后一个BOOL代表的是是否阻塞当前的子线程//    self performSelectorOnMainThread:<#(SEL)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>}

二.NSOperation

//NSOpreration 的两个子类,创建线程的作用    //NSOpreration并不能直接创建线程    //GCD与NSOpreration都是基于队列    NSInvocationOperation* IO = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(ThreadAction) object:nil];    //需要开启线程,不需要取消掉,会自动做的    //[IO start];        NSBlockOperation* BO = [NSBlockOperation blockOperationWithBlock:^{        for (int i = 0; i < 100; i ++) {            NSLog(@"杨帆");        }    }];    //[BO start];        //创建一个队列    NSOperationQueue* queue = [[NSOperationQueue alloc] init];    //最大的并发数量    //当我们设置为1的时候,队列实际上是串行的    //串行和并发是队列的一个名词    //对应到同步、异步    queue.maxConcurrentOperationCount = 2;    //添加一个依赖关系 后面的被依赖者先执行,前面的依赖者等着被依赖者执行完后再去执行    //如果两个线程之间需要依赖的话,先添加依赖关系,再去添加到队列中    [IO addDependency:BO];    //向队列里添加一项任务,先加进去的先执行    [queue addOperation:IO];    [queue addOperation:BO];


三.NSThread

一种也很不错的对多线程编程方式,但是线程的开启与关闭需要人工来执行,容易出错,而GDC就不存在着种问题

    //第一种初始化NSThread的方法    //绑定一个target action的事件,事件方法里做你要做的事情//    self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(ThreadAction) object:nil];//    //开始线程//    [self.thread start];        //自动开启一个 通过NSthread创建的线程    //项目开发中真正用到的多线程是在网络请求//    [NSThread detachNewThreadSelector:@selector(ThreadAction) toTarget:self withObject:nil];

-(void)ThreadAction{    //线程进入休眠状态1s    [NSThread sleepForTimeInterval:1.0f];    NSLog(@"当前线程%@",[NSThread currentThread]);    NSLog(@"主线程%@",[NSThread mainThread]);    //取消线程(仅仅是打了一个标识,标识的是这个线程可以取消掉了)   // [self.thread cancel];    //在这里线程真正的取消了    //[NSThread exit];    //结束当前的主线程    //exit(0);}


0 0