美文网首页iOS多线程技术性文章
iOS开发多线程以及子线程UI刷新

iOS开发多线程以及子线程UI刷新

作者: betterton | 来源:发表于2015-12-25 20:31 被阅读5524次

    "当您需要执行一个冗长的任务,但是不想让它阻止执行应用程序的其余部分。您可以使用线程来避免阻塞应用程序的主线程、处理用户界面和与事件相关的行动。线程也可以用来将大量的工作分成几个较小的工作,从而导致性能提高多核计算机上"

    说起线程 就不得不提起NSThread类NSOperationQueue和GCD 

    所以我们可以通过开子线程的方法来提高程序的运行速度,基本我们创建子线程的方法大致分为三种


    1.NSThread

    我们可以通过alloc init的方法来创建一个对象

    NSThread *read = [[NSThread alloc] initWithTarget:self selector:@selector(sniper) object:nil];

    同样的可以给这个线程命名

    read.name = @"subThread";

    但是需要注意的是 我们需要手动启动和释放这个线程

    [read start];

    [read release];

    如果我们不需要给这个线程名字的话也可以调用类方法直接开始线程

    [NSThread detachNewThreadSelector:@selector(sniper) toTarget:self withObject:nil];

    我们也可以通过方法来得知这个线程的名字和它的现场信息

    [NSThread currentThread];

    [NSThread isMainThread];


    2.NSOperation

    设计两个类NSOperation和NSOperationQueue

    要实现多线程首先创建NSOperation对象 然后加入到NSOperationQueue里

    需要注意的是NSOperation是一个抽象类 不能直接创建对象 但是我们可以通过它的两个子类NSInvocationOperation和NSBlockOperation来创建

    先创建一个队列 所有通过NSOperation创建的线程最终都要被添加到队列里执行

    NSOperationQueue *queu = [[NSOperationQueue alloc] init];

    指定该队列的最大并发数

    queu.maxConcurrentOperationCount = 2;

    创建线程并加入队列中

    NSInvocationOperation *invocationOne = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(sniper) object:nil];

    NSBlockOperation *blockOne = [NSBlockOperation blockOperationWithBlock:^{

    [self sniper];

    }];

    [queu addOperation:invocationOne];

    [queu addOperation:blockOne];

    同样的注意释放

    [invocationOne release];

    [invocationTwo release];


    3.GCD

    Grand Central Dispatch

    GCD的核心是队列管理和NSOperationQueue很相似

    但GCD是函数 执行速度快 效率高 

    同时加入了两个非常重要的概念: 任务 和 队列。

    任务:即操作,你想要干什么,说白了就是一段代码,在 GCD 中就是一个 Block,所以添加任务十分方便。任务有两种执行方式: 同步执行 和 异步执行,他们之间的区别是 是否会创建新的线程。

    同步执行:只要是同步执行的任务,都会在当前线程执行,不会另开线程。

    异步执行:只要是异步执行的任务,都会另开线程,在别的线程执行。

    同步(sync) 和 异步(async) 的主要区别在于会不会阻塞当前线程,直到 Block 中的任务执行完毕 。 

    队列:用于存放任务。一共有两种队列, 串行队列 和 并行队列。

    需要注意,GCD 会根据系统资源控制并行的数量,所以如果任务很多,它并不会让所有任务同时执行。

    创建并行队列

    dispatch_queue_t andQueue = dispatch_queue_create("com.baidu.www", DISPATCH_QUEUE_CONCURRENT);

    dispatch_async(andQueue, ^{

    [self sniper];

    });

    创建并行队列

    dispatch_queue_t sumQueue = dispatch_queue_create("com.baidu.www", DISPATCH_QUEUE_SERIAL);

    /* 向队列中添加任务 */

    dispatch_async(sumQueue, ^{

    [self sniper];

    });

    GCD是自带并行队列的 获取方法如下

    dispatch_queue_t globleQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_async(globleQueue, ^{

    [self sniper];

    });

    具体应用场景

    单例创建VC

    + (instancetype)defaultViewController {

    static ViewController *vc = nil;

    /* 只执行一次 */

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

    vc = [[ViewController alloc] init];

    });

    return vc;

    }

    图片的异步加载

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    NSURL *url = [NSURL URLWithString:@"http://img5.cache.netease.com/3g/2015/10/30/20151030124521c1f7e.jpg"];

    NSData *data = [NSData dataWithContentsOfURL:url];

    UIImage *image = [UIImage imageWithData:data];

    /* 使用GCD返回主线程 进行UI层面的赋值 */

    dispatch_async(dispatch_get_main_queue(), ^{

    self.iamgeView.image = image;

    });

    });

    相关文章

      网友评论

      • Joe_lisa:多条线程要同时刷新UI,要怎么处理,用异步
      • 刘栋:66666666

      本文标题:iOS开发多线程以及子线程UI刷新

      本文链接:https://www.haomeiwen.com/subject/uqpyhttx.html