美文网首页iOS 开发 将来跳槽用
iOS-进阶整理08 - GCD----多线程优化

iOS-进阶整理08 - GCD----多线程优化

作者: 简单也好 | 来源:发表于2016-04-15 19:36 被阅读270次

    一、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_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  
        //添加任务  
        dispatch_async(globalQueue, ^{  
            NSLog(@"全局队列0----%@",[NSThread currentThread]);  
        });  
        dispatch_async(globalQueue, ^{  
            NSLog(@"全局队列1----%@",[NSThread currentThread]);  
        });  
        dispatch_async(globalQueue, ^{  
            NSLog(@"全局队列2----%@",[NSThread currentThread]);  
        });  
        dispatch_async(globalQueue, ^{  
            NSLog(@"全局队列3----%@",[NSThread currentThread]);  
        });  
        dispatch_async(globalQueue, ^{  
            NSLog(@"全局队列4----%@",[NSThread currentThread]);  
        });  
        dispatch_async(globalQueue, ^{  
            NSLog(@"全局队列5----%@",[NSThread currentThread]);  
        });  
        dispatch_async(globalQueue, ^{  
            NSLog(@"全局队列6----%@",[NSThread currentThread]);  
        });  
        dispatch_async(globalQueue, ^{  
            NSLog(@"全局队列7----%@",[NSThread currentThread]);  
        });  
    }  
    

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

    
    //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)(55 * 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_t queue = dispatch_queue_create("concurrentTest", DISPATCH_QUEUE_CONCURRENT);  
          
        //添加任务  
        dispatch_async(queue, ^{  
            NSLog(@"这是第一个读取数据的任务。。。线程是:%@,是否主线程:%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);  
        });  
          
        dispatch_barrier_async(queue, ^{  
            NSLog(@"正在给数据库写入,阻塞其他任务");  
        });  
          
        dispatch_async(queue, ^{  
            NSLog(@"这是第二个读取任务。。。线程是:%@,是否主线程:%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);  
        });        
    }  
    

    相关文章

      网友评论

        本文标题:iOS-进阶整理08 - GCD----多线程优化

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