美文网首页
GCD的同步异步串行并行、NSOperation和NSOpera

GCD的同步异步串行并行、NSOperation和NSOpera

作者: 无所不知的程序员 | 来源:发表于2017-02-13 17:01 被阅读0次

    (1)GCD实现的同步异步、串行并行。

    ——同步sync应用场景:用户登录,利用阻塞

    ——串行异步应用场景:下载等耗时间的任务

    /**

    *  因为是异步,所以开通了子线程,但是因为是串行队列,所以只需要开通1个子线程(2),它们在子线程中顺序执行。最常用。

    -(void)gcdDemo1{

    dispatch_queue_t q1=dispatch_queue_create("com.hellocation.gcdDemo", DISPATCH_QUEUE_SERIAL);

    for (int i=0; i<10; i++) {

    dispatch_async(q1, ^{

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

    });

    }

    }

    *  因为是异步,所以开通了子线程,且因为是并行队列,所以开通了好多个子线程,具体几个,无人知晓,看运气。线程数量无法控制,且浪费。

    -(void)gcdDemo2{

    dispatch_queue_t q2=dispatch_queue_create("com.hellocation.gcdDemo", DISPATCH_QUEUE_CONCURRENT);

    for (int i=0; i<10; i++) {

    dispatch_async(q2, ^{

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

    });

    }

    }

    *  因为是同步,所以无论是并行队列还是串行队列,都是在主线程中执行

    -(void)gcdDemo3{

    dispatch_queue_t q1=dispatch_queue_create("com.hellocation.gcdDemo", DISPATCH_QUEUE_SERIAL);

    for (int i=0; i<10; i++) {

    dispatch_sync(q1, ^{

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

    });

    }

    }

    *  全局队列和并行队列类似(全局队列不需要创建直接get即可,而导致其没有名字,不利于后续调试)

    -(void)gcdDemo5{

    dispatch_queue_t q=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    for (int i=0; i<10; i++) {

    dispatch_sync(q, ^{

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

    });

    }

    for (int i=0; i<10; i++) {

    dispatch_async(q, ^{

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

    });

    }

    }

    *  因为是主线程,所以异步任务也会在主线程上运行(1)。而如果是同步任务,则阻塞了,因为主线程一直会在运行,所以后米的任务永远不会被执行。

    *  主要用处,是更新UI,更新UI一律在主线程上实现

    -(void)gcdDemo6{

    dispatch_queue_t q=dispatch_get_main_queue();

    for (int i=0; i<10; i++) {

    dispatch_sync(q, ^{

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

    });

    }

    // for (int i=0; i<10; i++) {

    // dispatch_async(q, ^{

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

    // });

    // }

    }

    (2)NSOperation和NSOperationQueue实现的线程管理

    /*

    *  1、只要是自己创建的队列,添加进来的操作(此处是block操作),都在子线程上(2)

    *  2、只要是在主队列中,添加进来的操作,都在主线程上(1)

    *  两个队列不能同时抢一个任务操作

    */

    -(void)opDemo1{

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

    NSBlockOperation *b=[NSBlockOperation blockOperationWithBlock:^{

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

    }];

    [queue addOperation:b];

    [[NSOperationQueue mainQueue]addOperation:b];

    }

    /**

    *  同上

    */

    -(void)opDemo2{

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

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

    [queue addOperation:i];

    [[NSOperationQueue mainQueue]addOperation:i];

    }

    -(void)helloWorld{

    NSLog(@"hello,world!");

    }

    /**

    *  依赖关系:(1)可以保证执行顺序,也使得开的子线程不会太多;(2)可以跨队列,而串行是不可以跨队列的,如最后更新UI则变成在主队列中。

    *  这是NSOperation(NSBlockOperation和NSInvocationOperation)和NSOperationQueue的优势

    */

    -(void)opDemo3{

    NSBlockOperation *op1=[NSBlockOperation blockOperationWithBlock:^{

    NSLog(@"下载图片 %@",[NSThread currentThread]);

    }];

    NSBlockOperation *op2=[NSBlockOperation blockOperationWithBlock:^{

    NSLog(@"修饰图片 %@",[NSThread currentThread]);

    }];

    NSBlockOperation *op3=[NSBlockOperation blockOperationWithBlock:^{

    NSLog(@"保存图片 %@",[NSThread currentThread]);

    }];

    NSBlockOperation *op4=[NSBlockOperation blockOperationWithBlock:^{

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

    }];

    [op4 addDependency:op3];

    [op3 addDependency:op2];

    [op2 addDependency:op1];

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

    //设置同一时刻最大开启的线程数,这是NSOperationQueue特有的

    [queue setMaxConcurrentOperationCount:2];

    [queue addOperation:op1];

    [queue addOperation:op2];

    [queue addOperation:op3];

    [[NSOperationQueue mainQueue]addOperation:op4];

    }

    (3)单例的实现(手写单例要求)dispatch_once运用,即重写类的allocWithZone方法

    @implementation WPObject

    +(instancetype)allocWithZone:(struct _NSZone *)zone{

    static WPObject *insta;

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

    insta=[super allocWithZone:zone];

    });

    return insta;

    }

    end

    相关文章

      网友评论

          本文标题:GCD的同步异步串行并行、NSOperation和NSOpera

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