zoukankan      html  css  js  c++  java
  • ios多线程 -- GCD 常见用法

    GCD 通信操作

    #pragma mark - GCD 通信
    - (void)sendMessage{
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            //耗时操作
            [self downLoad:@"http://..."];
    
            //回主队列刷新数据
            dispatch_async(dispatch_get_main_queue(), ^{
                //刷新UI操作
            });
        });
    }

    延时操作
    iOS常见的延时执行有2种方式
    (1)调用NSObject的方法

    // 2秒后再调用self的run方法
    [self performSelector:@selector(run) withObject:nil afterDelay:2.0];

    (2)使用GCD函数

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        // 2秒后异步执行这里的代码...
    });

    代码演示:

    #pragma mark - GCD 延迟
    - (void)delayModel:(CGFloat)time{
        // 经过延迟 time 秒后,回到当前线程,执行。不会卡住当前线程
        // 该方法在那个线程调用,那么run就在哪个线程执行(当前线程),通常是主线程
        //[self performSelector:@selector(downLoad:) withObject:@"delayModel" afterDelay:time];
    
        // GCD 实现
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(time * NSEC_PER_SEC)), queue, ^{
            [self downLoad:@"GCD---delayModel"];
        });
    }

    延时操作
    GCD延时操作

    一次性代码

    #pragma mark - GCD 一次性代码
    - (void)onceCore{
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
        // 只执行1次的代码(这里面默认是线程安全的)
            [self downLoad:@"onceCore"];
        });
    }

    一次性代码

    队列组

    #pragma mark - GCD 队列组
    - (void)groupQueue{
        // 1 获取全局队列
        /**
         * 优先级
         * DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高
         * DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默认(中)
         * DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低
         * DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后台
         */
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
        // 2 获取队列组
        dispatch_group_t group = dispatch_group_create();
    
        // 3 下载图片1
        //__block 修饰的值才能在 block 中改
        __block UIImage *image1 = nil;
        dispatch_group_async(group, queue, ^{
            //下载图片
            NSString *urlStr = @"http://b.hiphotos.baidu.com/image/pic/item/cdbf6c81800a19d8c58c800431fa828ba61e4627.jpg";
            NSURL *url = [NSURL URLWithString:urlStr];
            NSData *data = [NSData dataWithContentsOfURL:url];
            image1 = [UIImage imageWithData:data];
        });
    
        // 4 下载图片2
        __block UIImage *image2 = nil;
        dispatch_group_async(group, queue, ^{
            //下载图片
            NSString *urlStr = @"http://b.hiphotos.baidu.com/image/w%3D230/sign=fbc72e14362ac65c67056170cbf2b21d/e4dde71190ef76c666af095f9e16fdfaaf516741.jpg";
            NSURL *url = [NSURL URLWithString:urlStr];
            NSData *data = [NSData dataWithContentsOfURL:url];
            image2 = [UIImage imageWithData:data];
        });
    
    
        // 5 合并图片1, 2
        dispatch_group_notify(group, queue, ^{
            //获取图形上下文
            UIGraphicsBeginImageContextWithOptions(image1.size, NO, 0.0);
            //绘制第一张图片
            [image1 drawInRect:CGRectMake(0, 0, image1.size.width, image1.size.height)];
            //绘制第二张图片
            [image2 drawInRect:CGRectMake(0, 0, image2.size.width * 4, image2.size.height * 3)];
            //得到上下文的新图片
            UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
            //关闭上下文
            UIGraphicsEndImageContext();
    
            //回到主线程刷新界面
            dispatch_async(dispatch_get_main_queue(), ^{
                self.imageView.image = newImage;
            });
        });
    
    }

    队列组

    补充:

    有这么1种需求:
    
    首先:分别异步执行2个耗时的操作
    
    其次:等2个异步操作都执行完毕后,再回到主线程执行操作
    
    
    
    如果想要快速高效地实现上述需求,可以考虑用队列组
    
    dispatch_group_t group =  dispatch_group_create();
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 执行1个耗时的异步操作
    });
    
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 执行1个耗时的异步操作
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        // 等前面的异步操作都执行完毕后,回到主线程...
    });
  • 相关阅读:
    canvas
    学习总结
    后台管理人员项目,添加和查询的思路
    写了项目的一些心得
    学了一丢丢的正则皮毛
    已学的前端存储(学生)
    $.ajax()方法详解即自己遇到问题(新手)
    C#中 decimal 的四舍五入
    自己写一个C#数据结构:用List<T>实现一个简单的Stack
    【转】在CentOS 6.X上部署C# 开发环境
  • 原文地址:https://www.cnblogs.com/xiaocai-ios/p/7779776.html
Copyright © 2011-2022 走看看