iOS_经验(5)_GCD 使用总结

作者: 丶纳凉 | 来源:发表于2016-12-28 11:08 被阅读85次

    swift 版本:http://www.jianshu.com/p/6a8be281ddc8

    一丶目录

    GCD (Grand Central Dispatch) 苹果推荐使用的多线程技术

    1.多个网络请求并发处理
    2.使用快速迭代
    3.分线程,主线程通讯;
    4.延迟执行;
    5.一次性代码,默认线程安全
    6.队列组的使用
    7.dispatch_semaphore信号量的使用

    二丶代码:

    1.多个网络请求并发处理;

    dispatch_group_t dispatchGroup = dispatch_group_create();
    //发送第一个请求dispatch_group_enter(dispatchGroup);
    {
    //第一个请求回来
     dispatch_group_leave(dispatchGroup);
    }
    //发送第二个请求
    dispatch_group_enter(dispatchGroup);
    {
    //第二个请求回来    dispatch_group_leave(dispatchGroup);
    }
    dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
        //请求完成
    });
    

    2.快速迭代

    //快速迭代10次;顺序不定;线程不定
    dispatch_apply(10, dispatch_get_global_queue(0, 0), ^(size_t index)
        {
            NSLog(@"dispatch_apply--%ld--%@",index,[NSThread currentThread]);
        });
    

    3.分线程/主线程通讯

    
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
        dispatch_async(globalQueue, ^{
            //分线程->耗时的操作
            dispatch_async(dispatch_get_main_queue(), ^{
                //主线程
            });
        });
    

    4.延迟执行

    //延迟2秒
    NSLog(@"run--time:%@",[NSDate date]);
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"run--time:%@",[NSDate date]);
    });
    

    5.一次性代码,默认线程安全不会出现多个线程同时访问

        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            NSLog(@"只执行一次---%@",[NSThread currentThread]);
        });
        NSLog(@"n次--%@",[NSThread currentThread]);
    

    6.队列组的使用

    dispatch_group_t group = dispatch_group_create();
    
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    // 先执行3个耗时操作
    dispatch_group_async(group, queue, ^{
        for (int i = 0 ; i < 1000; i ++) {
            NSLog(@"1--%@--",[NSThread currentThread]);
        }
    });
    
    dispatch_group_async(group, queue, ^{
        for (int i = 0 ; i < 1000; i ++) {
            NSLog(@"2--%@--",[NSThread currentThread]);
        }
    });
    dispatch_group_async(group, queue, ^{
        for (int i = 0 ; i < 1000; i ++) {
            NSLog(@"3--%@--",[NSThread currentThread]);
        }
    });
    // 等到以上任务完成后才会执行这个notify任务
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"main--%@--",[NSThread currentThread]);
    });
    

    7.dispatch_semaphore信号量的使用

    //输出一个dispatch_semaphore_t类型且值为value的信号量;这里的传入的参数value必须大于或等于0,否则dispatch_semaphore_create会返回NULL
    dispatch_semaphore_t signal = dispatch_semaphore_create(1);
    dispatch_time_t overTime = dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC);
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_semaphore_wait(signal, overTime);
        NSLog(@"需要线程同步的操作1 开始");
        sleep(2);
        NSLog(@"需要线程同步的操作1 结束");
        //这个函数会使传入的信号量dsema的值加1;
        dispatch_semaphore_signal(signal);
    });
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(1);
        //信号量dsema的值减1
        //作用是这样的,如果dsema信号量的值大于0,该函数所处线程就继续执行下面的语句,并且将信号量的值减1;如果desema的值为0,那么这个函数就阻塞当前线程等待timeout(注意timeout的类型为dispatch_time_t,不能直接传入整形或float型数),如果等待的期间desema的值被dispatch_semaphore_signal函数加1了,且该函数(即dispatch_semaphore_wait)所处线程获得了信号量,那么就继续向下执行并将信号量减1。如果等待期间没有获取到信号量或者信号量的值一直为0,那么等到timeout时,其所处线程自动执行其后语句。
        dispatch_semaphore_wait(signal, overTime);
        NSLog(@"需要线程同步的操作2");
        dispatch_semaphore_signal(signal);
    });
    
    

    三丶注意

    1.block的使用,指针弱化情况;

    相关文章

      网友评论

        本文标题:iOS_经验(5)_GCD 使用总结

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