美文网首页
iOS开发-多线程知识点

iOS开发-多线程知识点

作者: 文帝_Wendy | 来源:发表于2019-07-26 15:40 被阅读0次

    一. NSThread 面向对象的,需要程序员手动创建线程,但不需要手动销毁。子线程间通信很难.

    1.创建子线程,再启动:

    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(testThread:) object:@"参数"];//有返回值,可以拿到返回值设置线程的优先级和名称

    [thread start];//需要手动开启

    2.创建并自动启动:

    [NSThread detachNewThreadSelector:@selector(testThread:) toTarget:self  withObject:@"便利构造器方式"];//没有返回值,不需要手动开启

    3.使用 NSObject 的方法创建并自动启动:

    [self performSelectorInBackground:@selector(run:)withObject:@"开启后台线程"];//没有返回值,不需要手动开启,只要是NSObject对象或者是NSObject的子类对象都可以用这种方法开启子线程,

    4.回到主线程的方法:

    [self performSelectorOnMainThread:@selector(backMainThread) withObject:nil waitUntilDone:YES];

    二. GCD - Grand Central Dispatch (任务 和 队列)

    1.基本概念:

    @1. 自动管理线程的生命周期(创建线程、调度任务、销毁线程);

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

    如果是 同步(sync) 操作,它会阻塞当前线程并等待 Block 中的任务执行完毕,然后当前线程才会继续往下运行; 如果是果是果是异步(async)操作,当前线程会直接往下执行,它不会阻塞当前线程。

    2.同步任务会阻塞当前线程,然后把 Block 中的任务放到指定的队列中执行,只有等到 Block 中的任务完成后才会让当前线程继续往下运行。

    NSLog("之前 - %@", NSThread.currentThread());

    dispatch_sync(dispatch_get_main_queue(), { () -> Void in

            NSLog("sync - %@", NSThread.currentThread());

    });

    NSLog("之后 - %@", NSThread.currentThread());

    结果:只会打印第一句:之前 - <NSThread: 0x7fb3a9e16470>{number = 1, name = main} ,然后主线程就卡死了

    3.队列组

    //1.创建队列组

    dispatch_group_t group = dispatch_group_create();

    //2.创建队列

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    //3.多次使用队列组的方法执行任务, 只有异步方法

    //3.1.执行3次循环

    dispatch_group_async(group, queue, ^{

      for (NSInteger i = 0; i < 3; i++) {

          NSLog(@"group-01 - %@", [NSThread currentThread]);

      }

    });

    //3.2.主队列执行8次循环

    dispatch_group_async(group, dispatch_get_main_queue(), ^{

      for (NSInteger i = 0; i < 8; i++) {

          NSLog(@"group-02 - %@", [NSThread currentThread]);

      }

    });

    //4.都完成后会自动通知

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{

      NSLog(@"完成 - %@", [NSThread currentThread]);

    });

    4.回到主线程的方法:

    dispatch_async(dispatch_get_main_queue(), ^{

    });

    三. NSOperation 基于GCD封装,完全面向对象.

    1.将要执行的任务封装到一个 NSOperation 对象中。将此任务添加到一个 NSOperationQueue 对象中。

    NSOperation 只是一个抽象类,所以不能封装任务。但它有 2 个子类用于封装任务。分别是:NSInvocationOperation 和 NSBlockOperation 。创建一个 Operation 后,需要调用 start 方法来启动任务,它会 默认在当前队列同步执行

    @1.创建NSInvocationOperation对象

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

    //开始执行

    [operation start];

    @2.创建NSBlockOperation对象

    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{

    NSLog(@"%@", [NSThread currentThread]);

    }];

    //添加多个Block (NOTE:addExecutionBlock 方法必须在 start() 方法之前执行,否则就会报错:)

    for (NSInteger i = 0; i < 5; i++) {

      [operation addExecutionBlock:^{

          NSLog(@"第%ld次:%@", i, [NSThread currentThread]);

      }];

    }

    //开始任务

    [operation start];

    2. 创建队列

    @1. 主队列

    NSOperationQueue *queue = [NSOperationQueue mainQueue];

    @2. 其他队列

    //1.创建一个其他队列 

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

    //2.创建NSBlockOperation对象

    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{

        NSLog(@"%@", [NSThread currentThread]);

    }];

    //3.添加多个Block

    for (NSInteger i = 0; i < 5; i++) {

        [operation addExecutionBlock:^{

            NSLog(@"第%ld次:%@", i, [NSThread currentThread]);

        }];

    }

    //4.队列添加任务

    [queue addOperation:operation];

    3. NSOperationQueue 有一个参数 maxConcurrentOperationCount 最大并发数,用来设置最多可以让多少个任务同时执行。当你把它设置为 1 的时候,就是串行了嘛!

    NSOperationQueue 还有一个添加任务的方法,- (void)addOperationWithBlock:(void (^)(void))block;

    4.回到主线程的方法:

    [[NSOperationQueue mainQueue] addOperationWithBlock:^{

    }];

    四. iOS多线程对比

    1. NSThread

    1)优点:轻量级,建立一个线程非常方便。

    2)缺点:需要手动管理所有的线程活动, 管理多个线程非常困难。

    2. NSOperation

    1)优点:自带线程周期管理,操作上可更注重自己逻辑; 可以监听任务执行状态,取消任务,限制最大并发数量。

    2)缺点:面向对象的抽象类,只能实现它或者使用它定义好的两个子类:NSInvocationOperation 和 NSBlockOperation。

    3. GCD 一个多核编程的解决方法。

    1)优点:用Block定义任务,使用起来非常灵活便捷;提供了更多的控制能力以及操作队列中所不能使用的底层函数;最高效,避开并发陷阱。

    2)缺点:是基于C语言的底层API。

    4. 选择小结

    1)简单而安全的选择NSOperation实现多线程即可。

    2)处理大量并发数据,又追求性能效率的选择GCD。

    特别鸣谢大神提供参考与转载链接:

    1.关于iOS多线程,你看我就够了 - 简书 ;

    2. 谈iOS多线程(NSThread、NSOperation、GCD)编程 - CocoaChina_一站式开发者成长社区

    相关文章

      网友评论

          本文标题:iOS开发-多线程知识点

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