iOS性能优化之GCD----多线程优化

2018-07-06  本文已影响0人  i_苏

一、GCD

GCD(Grand Central Dispatch)是Apple开发的一种多核编程技术。主要用于优化应用程序以支持多核处理器

GCD提供函数实现多线程开发,性能更高,功能更强大

首次发布在Mac OS X 10.6,iOS 4以上也可用


//定义一个回调函数

void function(void* str) {

    printf("回调函数  %s\n",str);

    NSLog(@"当前线程--%@",[NSThread currentThread]);

}

//串行队列,一次只执行一个任务

-(void)serialQueue {

    //创建队列

    dispatch_queue_t serialQuene = dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL);

    //为队列中添加任务

    //同步执行dispatch_sync,同步任务与当前的线程是一个线程,同步会阻塞当前线程

    //异步执行dispatch_async

    dispatch_sync(serialQuene, ^{

        NSLog(@"我是串行队列,第一步");

        NSLog(@"当前线程--%@",[NSThread currentThread]);

    });

    dispatch_async_f(serialQuene, "第二步", function);

    dispatch_async(serialQuene, ^{

        NSLog(@"第三步");

        NSLog(@"当前线程--%@",[NSThread currentThread]);

    });

    dispatch_async(serialQuene, ^{

        NSLog(@"第四步");

        NSLog(@"当前线程--%@",[NSThread currentThread]);

    });

    dispatch_async(serialQuene, ^{

        NSLog(@"第5步");

        NSLog(@"当前线程--%@",[NSThread currentThread]);

    });

    dispatch_async(serialQuene, ^{

        NSLog(@"第6步");

        NSLog(@"当前线程--%@",[NSThread currentThread]);

    });

    dispatch_async(serialQuene, ^{

        NSLog(@"第7步");

        NSLog(@"当前线程--%@",[NSThread currentThread]);

    });

    dispatch_async(serialQuene, ^{

        NSLog(@"第8步");

        NSLog(@"当前线程--%@",[NSThread currentThread]);

    });

    NSLog(@"最下面,线程%@",[NSThread currentThread]);

}

//并行队列

-(void)concurrentQuene {

    //创建并行队列

    dispatch_queue_t concurrent = dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);

    //添加任务

    dispatch_sync(concurrent, ^{

        NSLog(@"我是并行队列,第1步,当前线程--%@",[NSThread currentThread]);

    });

    dispatch_async_f(concurrent, "第二步", function);

    dispatch_async(concurrent, ^{

        NSLog(@"第3步,当前线程--%@",[NSThread currentThread]);

    });

    dispatch_async(concurrent, ^{

        NSLog(@"第4步,当前线程--%@",[NSThread currentThread]);

    });

    dispatch_async(concurrent, ^{

        NSLog(@"第5步,当前线程--%@",[NSThread currentThread]);

    });

    dispatch_async(concurrent, ^{

        NSLog(@"第6步,当前线程--%@",[NSThread currentThread]);

    });

    dispatch_async(concurrent, ^{

        NSLog(@"第7步,当前线程--%@",[NSThread currentThread]);

    });

    dispatch_async(concurrent, ^{

        NSLog(@"第8步,当前线程--%@",[NSThread currentThread]);

    });

}


全局队列

//系统提供的队列,全局队列,是并行的队列

-(void)globalQueue{

//系统提供的全局队列

//第一个参数:优先级,DISPATCH_QUEUE_PRIORITY_DEFAULT 0,  LOW -2, HIGH 2, BACKGROUND INT16_MIN

//第二个参数:Flags that are reserved for future use. Always specify 0 for this parameter.

dispatch_queue_tglobalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

//添加任务

dispatch_async(globalQueue, ^{

NSLog(@"全局队列0----%@",[NSThreadcurrentThread]);

    });

dispatch_async(globalQueue, ^{

NSLog(@"全局队列1----%@",[NSThreadcurrentThread]);

    });

dispatch_async(globalQueue, ^{

NSLog(@"全局队列2----%@",[NSThreadcurrentThread]);

    });

dispatch_async(globalQueue, ^{

NSLog(@"全局队列3----%@",[NSThreadcurrentThread]);

    });

dispatch_async(globalQueue, ^{

NSLog(@"全局队列4----%@",[NSThreadcurrentThread]);

    });

dispatch_async(globalQueue, ^{

NSLog(@"全局队列5----%@",[NSThreadcurrentThread]);

    });

dispatch_async(globalQueue, ^{

NSLog(@"全局队列6----%@",[NSThreadcurrentThread]);

    });

dispatch_async(globalQueue, ^{

NSLog(@"全局队列7----%@",[NSThreadcurrentThread]);

    });

}


全局队列和主队列结合使用

//GCD的常见使用方式,全局队列和主队列的结合使用

-(void)globalAndMainQueue{

    dispatch_async(dispatch_get_global_queue(0, 0), ^{

        //在全局队列中处理耗时的操作,因为全局队列执行的任务是在子线程中,不会阻塞主线程

        NSLog(@"子线程耗时操作");

        dispatch_async(dispatch_get_main_queue(), ^{

            //此时该block中所执行的任务是在主队列中,那么该任务就是在主线程中,在此处进行刷新UI的行为

            NSLog(@"刷新UI");

        });

    });

}


gcd的其他方法

//GCD中让某些代码只执行一次

-(void)onceToken {

    static UIImage *image = nil;

    static dispatch_once_t onceToken ;

    dispatch_once(&onceToken, ^{

        //此处的代码只会执行一次

        image = [[UIImage alloc]init];

        NSLog(@"只会执行一次的代码");

    });

}

//GCD中的其他方法

-(void)otherGCD {

    //在延迟时间点执行任务

    //1.从什么时间开始计算

    //2.从此时间多少秒执行

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        NSLog(@"after 5秒延迟执行 --- %@",[NSThread currentThread]);

    });

//    sleep(5);线程沉睡

    //重复执行

    //1.重复执行的次数

    //2.队列

    dispatch_apply(3, dispatch_get_global_queue(0, 0), ^(size_t count) {

        NSLog(@"在主队列重复执行3次 %ld",count);

    });

}


gcd——group

//GCD 将任务添加到队列中

-(void)groupGCD {

    //dispatch_group_async可以实现监听一组任务是否完成,完成后得到通知执行其他的操作。这个方法很有用,比如你执行三个下载任务,当三个任务都下载完成后你才通知界面说完成的了。下面是一段例子代码:

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_group_t group = dispatch_group_create();

    dispatch_group_async(group, queue, ^{

        [NSThread sleepForTimeInterval:1];

        NSLog(@"group1");

    });

    dispatch_group_async(group, queue, ^{

        [NSThread sleepForTimeInterval:2];

        NSLog(@"group2");

    });

    dispatch_group_async(group, queue, ^{

        [NSThread sleepForTimeInterval:3];

        NSLog(@"group3");

    });

    //当所有group里面的任务执行完,就执行notify

    //在执行notify之前至少给队列里放一个任务

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{

        NSLog(@"updateUi");

    });

}


gcd_barrier

//数据库的读取 可以并发执行,通过GCD里面的并行队列实现

//数据库的写入  只能串行执行,通过GCD里面的串行队列实现

//但项目中,有读取和写入,通过dispatch_barrier_async实现,此任务执行的时候,其他任务停止执行

-(void)barrierGCD {

//创建并发队列

dispatch_queue_tqueue = dispatch_queue_create("concurrentTest", DISPATCH_QUEUE_CONCURRENT);

//添加任务

dispatch_async(queue, ^{

NSLog(@"这是第一个读取数据的任务。。。线程是:%@,是否主线程:%d",[NSThreadcurrentThread],[[NSThreadcurrentThread]isMainThread]);

    });

    dispatch_barrier_async(queue, ^{

NSLog(@"正在给数据库写入,阻塞其他任务");

    });

dispatch_async(queue, ^{

NSLog(@"这是第二个读取任务。。。线程是:%@,是否主线程:%d",[NSThreadcurrentThread],[[NSThreadcurrentThread]isMainThread]);

    });

}

上一篇下一篇

猜你喜欢

热点阅读