OC多线程

多线程

在今天的多线程中主要包括以下几个方面:①串行队列②并行队列③分组队列④一次性⑤障碍队列⑥延迟⑦重复

1. 串行队列

一个应用只有一个主线程, 主线程主要用于用户交互和界面显示

1 . 创建串行队列

//(1). 获取系统创建好的串行队列, 在主线程中实现线程同步(C 语言层级, 执行效率非常高, 但容易出现卡顿), 获取方法如下:
dispatch_queue_t queue1 = dispatch_get_main_queue();
//(2). 自己创建串行队列, 队列在子线程中实现线程同步
//第一个参数(const char *label)是队列的唯一标识
//第二个参数(dispatch_queue_attr_t attr)用于指定串行队列
dispatch_queue_t queue2 = dispatch_queue_create("com.baidu.www",  DISPATCH_QUEUE_SERIAL);

2 . 往队列中添加任务

//第一个参数(dispatch_queue_t queue)是队列名
//第二个参数(<#^(void)block#>)是 block 块
dispatch_async(queue2, ^{//可以进行具体操作
        NSLog(@"任务一 : %@", [NSThread currentThread]);//输出结果中的number 为 1时说明系统的队列
    });

3 . 释放

//当使用 create 创建队列时,使用完之后需要释放
dispatch_release(queue2);
2. 并行队列

系统创建好了四个队列, 按照优先级分别是①DISPATCH_QUEUE_PRIORITY_BACKGROUND
②DISPATCH_QUEUE_PRIORITY_DEFAULT
③DISPATCH_QUEUE_PRIORITY_LOW
④DISPATCH_QUEUE_PRIORITY_HIGH

1 . 创建并发(并行)队列

//(1). 获取并使用系统创建好的并发队列
//第一个参数(long identifier)是队列的优先级
//第二个参数(unsigned long flags)是预留参数
dispatch_queue_t queue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//(2). 自己创建并发队列
//第一个参数是唯一标识
//第二个参数是将该队列指定为并发队列
dispatch_queue_t queue2 = dispatch_queue_create("com.lanou3g.leo", DISPATCH_QUEUE_CONCURRENT);

2 . 往队列中添加任务

dispatch_async(queue2, ^{
        NSLog(@"任务一 : %@", [NSThread currentThread]);
});

3 . 释放

dispatch_release(queue2);
3. 分组队列

当数据很大时, 可以使用分组队列,一部分一部分的请求数据

1 . 创建并行队列(这里以系统队列为例, 当然还可以使用自己创建的队列)

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

2 . 创建分组

dispatch_group_t group = dispatch_group_create();

3 . 往分组中添加任务

dispatch_group_async(group, queue, ^{
    NSLog(@"请求 0 - 10M 的数据");
});
dispatch_group_async(group, queue, ^{
    NSLog(@"请求10 - 20M 的数据");
});
dispatch_group_async(group, queue, ^{
    NSLog(@"请求20 - 30M 的数据");
});
dispatch_group_async(group, queue, ^{
    NSLog(@"请求30 - 40M 的数据");
});
//当分组内的所有任务完成之后触发
dispatch_group_notify(group, queue, ^{
    NSLog(@"数据拼接操作");
});

4 . 释放

dispatch_release(group);
4. 一次

一次性线程, 顾名思义就是只执行一次的线程, 在 OC 中最突出的就是单例类的初始化

//单例类的初始化方法
+ (id)mainSingleton {
    static Singleton *singleton = nil;
//    这是之前的定义方法
//    @synchronized(self) {
//        if (!singleton) {
//            singleton = [[Singleton alloc] init];
//        }
//    }
//    return singleton;

//GCD : 创建的队列都是轻量级的, 这里用到的都是 GCD
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    //写只执行一次的代码
    singleton = [[Singleton alloc] init];
});
return singleton;
}
5. 障碍队列

障碍任务的作用: 可以保证障碍之后到的并发任务, 必须在张安之前的并发任务全部执行完成之后, 才可以继续往下执行(注意: 如果添加障碍任务, 必须要使用自己创建的并发队列)

1 . 创建并发队列

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

2 . 往队列中添加队列

    dispatch_async(queue, ^{
        NSLog(@"A 写入文件file1");
    });
    dispatch_async(queue, ^{
        NSLog(@"B 写入文件file2");
    });
    dispatch_async(queue, ^{
        NSLog(@"C 写入文件file3");
    });
    //添加障碍任务
    dispatch_barrier_async(queue, ^{
        NSLog(@"这是一个障碍任务");
    });
    dispatch_async(queue, ^{
        NSLog(@"D 读取文件file3");
    });
    dispatch_async(queue, ^{
        NSLog(@"E 读取文件file1");
    });

3 . 释放

dispatch_release(queue);
6. 延迟
//第一个参数(delayInSeconds) 是延迟时间(秒)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"hh");
    });
//其中的dispatch_get_main_queue() 是在主线程中执行, 如果想在子线程中执行, 此处改为子线程即可
7. 重复
//dispatch_get_main_queue 主线程重复时即使重复一次, 也会卡死
//反复执行并发队列至少有一次在主线程中执行.
dispatch_apply(10, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t index) {
         NSLog(@"反复执行的次数%ld, 当前线程%@", index, [NSThread currentThread]);
     });//size_t 之后要添加参数名, 比如 index
注意

1 . 关于dispatch_queue_create
a. 在使用dispatch_queue_create方法创建自己的队列时, 需要注意第二个参数用于指定串行队列或是并行队列, 具体如下:
①DISPATCH_QUEUE_CONCURRENT : 并行队列
②DISPATCH_QUEUE_SERIAL : 串行队列
b. 在使用dispatch_queue_create方法创建自己的队列之后, 需要将该队列释放(只要方法中有 create 的都需要释放)
2 . 关于dispatch_async

使用异步方法而不是同步方法是因为, 同步方法易出现卡顿现象, 用户交互差

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值