多线程(中) 1.NSThread 2.NSOperationQueue 3.NSObject 4.GCD

1.NSThread
// 使用NSThread方式创建子线程时, 一定要注意, 在子线程中执行的方法中添加自动释放池! 原因:autoReleasePool影响一些autoRelease标签的对象释放, 而系统只会在主线程中, 默认帮助我们添加自动释放池,而在子线程中, 系统不会帮我们自动添加自动释放池, 存在内存泄露
Thread 创建方法 有两种

    // 1.对象创建方法, 使用NSThread创建一个子线程
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(objectThread:) object:self];
    //对象创建方式需要手动的执行
    [thread start];

1.2 类的创建方式, 不需要我们手动执行

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

1.3几个常用的属性


   [NSThread isMainThread]//YES就是当前主线程, NO就是子线程
   [NSThread currentThread]//获取当前的线程

2.NSOperationQueue
*NSOperation是一个抽象类, 我们都是使用它的子类
*NSOperation的子类其实就是一个任务, 自己本身没有开辟子线程的能力, 所以说该任务在主线程中执行就是在主线程; 在子线程执行就是在子线程

2.1 NSInvocationOperation

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

   //可能用到的属性
   // invoOperation.isCancelled, 判断这个任务有没有取消, 当调用了cancel的方法, 这个属性就变成了YES, 这个cancel也取消不了正在执行的任务, 任务还没开始执行, 就可以取消, 同NSTHread一样   
    //执行该任务
    [invoOperation start];

2.2 NSBlockOperation

    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
        //里面写具体的操作
        NSLog(@"这是一个BlockOperation");
    }];
    //执行这个任务
    [blockOperation start

2.3 NSOperationQueue


    //这是任务队列, 就是一个容器, 里面都是一个个任务, 可以是block任务, 也可以是invocation任务
    //NSOperationQueue才具有开辟子线程的能力,
    //用来管理里面的所有任务
    //相当于开辟了一个线程队列
    NSOperationQueue *queue= [[NSOperationQueue alloc] init];
    //创建一个任务
    NSInvocationOperation *inv = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invAction) object:nil];

    NSBlockOperation *block1 = [NSBlockOperation blockOperationWithBlock:^{
        for (int i = 0; i < 100; i++) {
            NSLog(@"BB");
        }
    }];
    NSBlockOperation *block2 = [NSBlockOperation blockOperationWithBlock:^{
        for (int i = 0; i < 100; i++) {
            NSLog(@"CC");
        }

    }];
    //把3个任务添加到线程队列中
    //添加到队列之后, 系统机会自己开启执行任务

    //queue.maxConcurrentOperationCount  = 3;//设置最大并发数, 默认值为-1
    //队列FIFO, 先进先出, 所以当我们设置最大并发数为1的时候, 会按照添加的顺序, 先把最早加入队列的完成之后, 再去执行后添加的任务
    // 设置依赖关系
    // 一定要在任务添加到队列之前设置依赖关系
    //A addDependency: B意思就是: A依赖于B, A的执行, 依赖B的完成

    // *添加以来的时候, 要避免循环依赖, 循环依赖会导致两个任务都不执行
    [block1 addDependency:block2];

    [queue addOperation:inv];
    [queue addOperation:block1];
    [queue addOperation:block2];

3.NSObject 创建及用法

   //使用NSObiect类中的方法开辟子线程
    [self performSelectorInBackground:@selector(backgroundAction) withObject:nil];
}

// 在子线程中执行的方法
// *在下面方法中, 处理UI界面东西, 记得回主线程中
//1.NSThread, NSObject这两种技术需要加上字典释放池(无论在ARC还是MRC都需要加)
- (void)backgroundAction {
    @autoreleasepool {
        NSLog(@"---是在主线程中吗--%d", [NSThread isMainThread]);
    }
}

4 .GCD
//GCD中只有两种类型的队列(dispatch_queue_t):
//1.串行(任务一个个执行)
//1.1系统自带的, 系统自带的串行队列是主线列

   dispatch_queue_t systemSerial = dispatch_get_main_queue(); 
//1.2自己创建
      dispatch_queue_t createSerial = dispatch_queue_create("com.lanou3g.createSerial1", DISPATCH_QUEUE_SERIAL);  

//2.并行
//2.1系统自带
//第一个参数队列优先级, 选择默认的
//1. 预留参数, 没有任何作用 2.*子线程队列, 也就是说, 将来在该队中执行的任务, 都是在子线程中完成


   dispatch_queue_t systemConcurrent = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
   //2.2自己创建
    dispatch_queue_t createConcurrent = dispatch_queue_create("com.currenQueue", DISPATCH_QUEUE_CONCURRENT);

向队列中添加任务, 在队列中执行这个任务—dispath-async()

    dispatch_async(createSerial, ^{
        for (int i = 0; i < 100; i++) {
            NSLog(@"AAA");
        }
        NSLog(@"---%d", [NSThread isMainThread]);
        //放置耗时操作
    });
    dispatch_async(createSerial, ^{
        for (int i = 0; i < 100; i++) {
            NSLog(@"BBB");
        }
    });

延迟执行代码的函数—dispatch_after()

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        //参数就是想推迟的
        NSLog(@"---after:%d", [NSThread isMainThread]);
    });
    */

只执行一次的函数(无论在哪一个线程都直走一次), 用于创建单例—dispatch_once()

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        // 只执行一次的代码

    });

重复执行 —dispatch_apply()

 //  执行的次数
    //  队列(使用子线程队列)--线程死锁
    //  block里面的参数
    dispatch_apply(5, createConcurrent, ^(size_t t){
        NSLog(@"卢英杰是一夜%luÅ次郎", t);
    });

GCD-分组——-


    //GCD分组的类型
    //分组
    dispatch_group_t createGroup = dispatch_group_create();
    dispatch_group_async(createGroup, createConcurrent, ^{
        //想检测的任务1
        NSLog(@"AAAA");
    });
    dispatch_group_async(createGroup, createConcurrent, ^{
        NSLog(@"BBBB");
    });
    dispatch_group_async(createGroup, createConcurrent, ^{
        NSLog(@"CCCC");
    });

    // 分组有这样一个特性:标记在组中的任务都完成之后, 可以通知下面的函数执行
    dispatch_group_notify(createGroup, systemSerial, ^{
        NSLog(@"主线程刷新UI---%d", [NSThread isMainThread]);
    });

—*调整线程之间的次序(线程同步)
// 障碍

dispatch_async(createConcurrent, ^{
    for (int i = 0; i < 100; i++) {
        NSLog(@"AAAAA");
    }
});
dispatch_async(createConcurrent, ^{
    for (int i = 0; i < 100; i++) {
        NSLog(@"BBBBB");
    }
});
//添加一个障碍
dispatch_barrier_async(createConcurrent, ^{
    NSLog(@"我是分割线");
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值