• iOS 多线程讲解2


    1、GCD其他方法

    1、GCD应用 单例模式

        static dispatch_once_t onceToken;

        dispatch_once(&onceToken, ^{

            NSLog(@"执行一次%@",[NSThread currentThread]);

        });

    2、GCD延时操作

    (1)第一种方式

    [self performSelector:@selector(handleAction) withObject:nil afterDelay:0];

    (2)第二种方式

    DISPATCH_TIME_NOW 从现在开始

    delayInSeconds 延迟几秒

    dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC));

        

    when dispatch_time_t

        

    dispatch_after(time, dispatch_get_main_queue(), ^{

            

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

     });

    3、调度组

     

    (1)第一种形式

     

    //创建调度组

    dispatch_group_t group = dispatch_group_create();

    //获取全局队列

    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

    //调度组的异步请求

    dispatch_group_async(group, queue, ^{

            

    [NSThread sleepForTimeInterval:2];

    NSLog(@"下载第一张图");

    });

    dispatch_group_async(group, queue, ^{

    [NSThread sleepForTimeInterval:3];

    NSLog(@"下载第二张图");

    });

        

    dispatch_group_async(group, queue, ^{

    [NSThread sleepForTimeInterval:1];

    NSLog(@"下载第三张图");

    });

        

    dispatch_group_async(group, queue, ^{

    [NSThread sleepForTimeInterval:5];        

    NSLog(@"下载第四张图");

    });

        

    //notify通知,当所有异步请求完成时调用dispatch_group_notify

    dispatch_group_notify(group, queue, ^{

    NSLog(@"更新UI);

    });

    (2)第二种形式

    //创建调度组

    dispatch_group_t group = dispatch_group_create();

    //获取全局队列

    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

        

    //进入队列

    dispatch_group_enter(group);

    dispatch_async(queue, ^{

            

    [NSThread sleepForTimeInterval:2];

    NSLog(@"下载第一张图");

            

    //离开队列

    dispatch_group_leave(group);

    });

        

    dispatch_group_enter(group);

    dispatch_async(queue, ^{

            

    [NSThread sleepForTimeInterval:1];

    NSLog(@"下载第er张图");

    dispatch_group_leave(group);

    });

        

    dispatch_group_enter(group);

    dispatch_async(queue, ^{

            

    [NSThread sleepForTimeInterval:3];

    NSLog(@"下载第san张图");        

    dispatch_group_leave(group);

    });

        

    //等待调度队列wait相当于一个阻塞状态

    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

    NSLog(@"更新UI”);

    (4)中断操作

    dispatch_barrier_async一定是自定义队列

    这里指定的并发队列应该是自己通过dispatch_queue_create函数创建的。

    如果你传的是一个串行队列或者全局并发队列,这个函数等同于dispatch_async函数。

        

    dispatch_queue_t queue = dispatch_queue_create("com.bjsxt", DISPATCH_QUEUE_CONCURRENT); //dispatch_get_global_queue(0, 0);

        

    dispatch_async(queue, ^{

    [NSThread sleepForTimeInterval:1];

    NSLog(@"1");

    });

        

    dispatch_async(queue, ^{

    [NSThread sleepForTimeInterval:3];     

    NSLog(@"2");

    });

        dispatch_async(queue, ^{

            

            [NSThread sleepForTimeInterval:2];

            

            NSLog(@"3");

        });

        

    //中断操作dispatch_barrier_async

        dispatch_barrier_async(queue, ^{

            NSLog(@"--------");

            [NSThread sleepForTimeInterval:1];

            

        });

        

        dispatch_async(queue, ^{

            

            [NSThread sleepForTimeInterval:1];

            NSLog(@"4");

        });

        dispatch_async(queue, ^{

            NSLog(@"5);

     });

    (7)遍历操作

        

    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

        

    //iterations 遍历的次数

        dispatch_apply(5, queue, ^(size_t i) {

            NSLog(@"%@",@(i));

     });

    2、NSOperation基础

    (1)创建方式

    1)基于一个对象和selector来创建操作。如果你已经有现有的方法来执行需要的任务,就可以使用这个类

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

    2)能够并发地执行一个或多个block对象,所有相关的block都执行完之后,操作才算完成

    NSBlockOperation * op = [NSBlockOperation blockOperationWithBlock:^{

            

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

    NSLog(@"第一个操作);

    }];

    3)获取主队列

    [[NSOperationQueue mainQueue] addOperationWithBlock:^{    

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

                NSLog(@"更新UI");

    }];

    3)如果我们想在一个NSOperation执行完毕后做一些事情,就调用NSOperation的setCompletionBlock方法来设置想做的事情

    [op setCompletionBlock:^{ NSLog(@"完成); }];

    4) 通过addExecutionBlock方法添加block操作,开启多个线程

    [op addExecutionBlock:^{

            

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

            

            NSLog(@"第二个操作");

    }];

    (2)开始执行任务

    1)一个NSOperation对象可以通过调用start方法来执行任务,默认是同步执行的。

    [op start];(同步执行)

    2)NSOperation是基于GCD的,把GCD的block封装成opertion,

    NSOperationQueue是全局队列封装

    将NSOperation添加到一个NSOperationQueue(操作队列)中去执行,而且是异步执行的。

    //添加一个block形式的operation

    [queue addOperationWithBlock:^{

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

    }];

    (3)添加任务

    NSOperation添加到queue之后,通常短时间内就会得到运行。

    waitUntilFinished yes 操作完成后执行下面的代码 no 先执行下面的代码

    [queue addOperations:@[op,op2] waitUntilFinished:NO];

    (4)设置最大并发数

    self.queue.maxConcurrentOperationCount = 2;

    (5)设置依赖关系

    //添加NSOperation的依赖对象

    [op2 addDependency:op1];

    [op3 addDependency:op2];

    注意:不能创建环形依赖,如A依赖B,B依赖A,这是错误的

    (6)设置优先级

    设置优先级,数据量少看不出

    op1.queuePriority = -4;

    (7)设置挂起状态

    暂停一个queue不会导致正在执行的operation在任务中途暂停,只是简单地阻止调度新Operation执行

    挂起状态设置

    self.queue.suspended = !self.queue.suspended;

    (8)取消queue中的操作

    1.取消queue中所有的操作

    [self.queue cancelAllOperations];

    2.取消单个操作

    [op cancel];

    3、GCD和NSOperation的区别

    GCD -- (iOS4.0)多线程解决方案

    将任务(block)添加到队列(串行,并行(全局队列)),指定执行任务的方法。(同步,异步)

    拿到dispatch_get_main_queue,线程之间的通信

    NSOperation -- (iOS2.0)  (后经苹果改造)

    将操作添加到队列里

    [NSOperationQueue mainQueue]  获取主队列,将任务添加到主队列,就会在主线程中执行

    NSOperation可以设置最大并发数(用GCD处理,比较麻烦)

    可以暂停可以继续,也就是挂起操作

    取消所有的任务

    设置依赖关系

  • 相关阅读:
    Android数据适配器(Adapter)优化:高效ViewHolder
    touch-css-margintop问题
    抽奖
    scroll03-节日两侧的渲染
    scroll02-滚动时显示当前主题菜单状态
    浏览器背景色半透明效果。
    scroll01-滚动到一定高度时,显示导航栏
    layout01-在布局ul时,给li设置margin-right的时候,每行的最后一个li有margin-right 导致ul 看上去不居中的问题
    placehoder兼容
    day03
  • 原文地址:https://www.cnblogs.com/PSSSCode/p/5281091.html
Copyright © 2020-2023  润新知