开发者iOS技术点多线程

iOS笔记-多线程相关(pthread 、NSThread 、G

2016-01-24  本文已影响2127人  Developer_Yancy
随机配图

pthread

/*
参数:
     1. 线程代号的地址
     2. 线程的属性
     3. 调用函数的指针
        - void *(*)(void *)
        - 返回值 (函数指针)(参数)
        - void * 和 OC 中的 id 是等价的
     4. 传递给该函数的参数
返回值:
     如果是0,表示正确
     如果是非0,表示错误码
*/
NSString *str = @"lnj";
    pthread_t thid;
    int res = pthread_create(&thid, NULL, &demo, (__bridge void *)(str));
    if (res == 0) {
        NSLog(@"OK");
    } else {
        NSLog(@"error %d", res);
    }

NSThread

    // 1.创建线程
    NJThread *thread = [[NJThread alloc] initWithTarget:self selector:@selector(demo:) object:@"lnj"];
    // 设置线程名称
    [thread setName:@"xmg"];
    // 设置线程的优先级
    // 优先级仅仅说明被CPU调用的可能性更大
    [thread setThreadPriority:1.0];
    // 2.启动线程
    [thread start];

// 1.创建线程
[NSThread detachNewThreadSelector:@selector(demo:) toTarget:self withObject:@"lnj"];

// 1.创建线程
// 注意: Swift中不能使用, 苹果认为这个方法不安全
    [self performSelectorInBackground:@selector(demo:) withObject:@"lnj"];

@synchronized(锁对象) { // 需要锁定的代码  }



[self performSelectorInBackground:@selector(download) withObject:nil];

/*
 waitUntilDone是否等待被调用方法执行完成,有可能也会等待调用方法的执行完成!
 YES: 等待被调用线程执行完毕再执行后面的代码
 NO : 不用等待被调用线程执行完毕就可以执行后面的代码
 */

[self performSelectorOnMainThread:@selector(showImage:) withObject:[UIImage imageWithData:data] waitUntilDone:YES];


---

###GCD
- GCD中有2个核心概念
  + 任务:执行什么操作
  + 队列:用来存放任务

- 执行任务
  + 同步方法: dispatch_sync
  + 异步方法: dispatch_async
  + 同步和异步的区别
      * 同步:只能在当前线程中执行任务,不具备开启新线程的能力
      * 异步:可以在新的线程中执行任务,具备开启新线程的能力

- 队列
  + 并发队列
      * 可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)
      * 并发功能只有在异步(dispatch_async)函数下才有效
  + 串行队列
      * 让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)

- 注意点
  + 同步和异步主要影响:能不能开启新的线程
      * 同步:只是在当前线程中执行任务,不具备开启新线程的能力
      * 异步:可以在新的线程中执行任务,具备开启新线程的能力
  + 并发和串行主要影响:任务的执行方式
      * 并发:允许多个任务并发(同时)执行
      * 串行:一个任务执行完毕后,再执行下一个任务

- 各种任务队列搭配
  + 同步 + 串行
  + 同步 + 并发
  + 异步 + 串行
  + 异步 + 并发
  + 异步 + 主队列
  + 同步 + 主队列
      

- GCD线程间通信

```objc
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  // 执行耗时的异步操作...
    dispatch_async(dispatch_get_main_queue(), ^{
      // 回到主线程,执行UI刷新操作
      });
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    // 2秒后执行这里的代码...
});

static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 只执行1次的代码(这里面默认是线程安全的)
});


- 快速迭代

```objc
dispatch_apply(10, dispatch_get_global_queue(0, 0), ^(size_t index){
  // 执行10次代码,index顺序不确定
});

dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);


- 队列组

```objc
dispatch_group_t group =  dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  // 执行1个耗时的异步操作
});
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  // 执行1个耗时的异步操作
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
  // 等前面的异步操作都执行完毕后,回到主线程...
});

NSOperation

使用NSOperation子类的方式有3种

1.NSInvocationOperation
2.NSBlockOperation
3.自定义子类继承NSOperation,实现内部相应的方法

注意
- 默认情况下,调用了start方法后并不会开一条新线程去执行操作,而是在当前线程同步执行操作
- 只有将NSOperation放到一个NSOperationQueue中,才会异步执行操作

注意
- 只要NSBlockOperation封装的操作数 > 1,就会异步执行操作


NSOperationQueue

最大并发数

队列的取消、暂停、恢复

操作依赖

操作的监听

自定义NSOperation

NSOperationQueue和GCD对比

+ GCD
    * 并发: 自己创建, 全局
    * 串行: 自己创建, 主队列
+ NSOperationQueue
    * 主队列: mainQueue
        + 永远在主线程中执行
    * 自己创建队列: alloc init
        + 会开启新的线程, 在子线程中执行
+ 如何控制并行和串行
    * maxConcurrentOperationCount = -1 ; 并行
    * 默认就是并行
    * maxConcurrentOperationCount = 1 ; 串行
    * maxConcurrentOperationCount = 0 ; 不会执行
+ 使用步骤:
    * 和GCD一样
    * 1.创建操作(任务)
    * 2.将任务添加到队列中
+ 快速添加任务的方法
// 只要利用队列调用addOperationWithBlock:方法, 系统内部会自动封装成一个NSBlockOperation \
    然后再添加到队列中
[queue addOperationWithBlock:^{
        NSLog(@"3 == %@", [NSThread currentThread]);
    }];

- (void)main
{
    // 耗时操作1
    for (int i = 0; i < 10000; i++) { // 500
        NSLog(@"%i ==== %@", i, [NSThread currentThread]);
    }
    NSLog(@"++++++++++++++++++++++++++++++++++++++");
    if (self.isCancelled) {
        return;
    }

    // 耗时操作2
    for (int i = 0; i < 10000; i++) { // 500
        NSLog(@"%i ==== %@", i, [NSThread currentThread]);
    }
    if (self.isCancelled) {
        return;
    }
    NSLog(@"++++++++++++++++++++++++++++++++++++++");
    // 好所操作3
    for (int i = 0; i < 10000; i++) { // 500
        NSLog(@"%i ==== %@", i, [NSThread currentThread]);
    }
}
 // 3.添加依赖
    [op5 addDependency:op1];
    [op5 addDependency:op2];
    [op5 addDependency:op3];
    [op5 addDependency:op4];
上一篇 下一篇

猜你喜欢

热点阅读