GCD入门(二)啦

作者: 诺馨 | 来源:发表于2016-05-24 21:16 被阅读48次

废话不多说,直接从GCD所提供的函数说起。

dispatch_once

相信大家对单例模式可谓是司空见惯了吧,常见的实现方式是:在某个类中编写名为sharedInstance的类方法,该方法只会返回该类共用的单例实例,而不会在每次调用时都创建新的实例。假设有个类为FTHImage,一般会这样写:

#import "FTHImage.h"

@implementation FTHImage
+ (FTHImage *)sharedImage {
    static FTHImage *shareImage = nil;
    @synchronized (self) {
        if (!shareImage) {
            shareImage = [[self alloc] init];
        }
    }
    return shareImage;
}
@end

但是这种单例实现并不是线程安全的,单例实例化代码会执行多次,而不是一次。还好,GCD引入一项特性,即dispatch_once函数。

void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);```
- 此函数有个类型为dispatch_once_t 的参数(其实可以将它看作是一个“标记”)以及一个块参数。
- 使用dispatch_once简化了代码而且彻底保证线程安全,开发者无需担心加锁以及同步的问题,因为GCD都会帮你在底层处理搞定。
- 另外每次调用都必须使用完全相同的标记,所以标记应该声明为static,由此可以保证编译器在每次执行单例方法时都会复用这个变量,从而不会创建新的变量。
######再次说明,编写只需执行一次的线程安全代码,通过GCD提供的dispatch_once函数就可以实现。并且在性能方面,比采用@synchronized的方式来得更高效。

用此函数改写上面的代码:

import "FTHImage.h"

@implementation FTHImage

  • (FTHImage *)sharedImage {
    static FTHImage *shareImage = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    shareImage = [[self alloc] init];
    });
    return shareImage;
    }
    @end
####dispatch_async 
当你需要在<b>后台执行</b>一个基于网络或 CPU 紧张的任务时就使用 dispatch_async ,这样就不会阻塞当前线程。dispatch_async 添加一个 Block 到队列就立即返回了。任务会在之后由 GCD 决定执行。使用如下:

dispatch_async(queue, ^{
//长时间处理,例如下载网络图片,获取网络数据,数据库访问等
dispatch_async( dispatch_get_main_queue(), ^{
//只在主线程可以执行的处理
//例如用户界面更新
});
});

来个简单的例子,好吧,还是以图片下载后显示为例。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
    // 异步下载图片
    NSURL *url = [NSURL URLWithString:@"http://xx.jpg"];
    NSData *data = [NSData dataWithContentsOfURL:url]; //
    UIImage *image = [UIImage imageWithData:data];
    
    // 回到主线程显示图片
    dispatch_async(dispatch_get_main_queue(), ^{
        self.imageView.image = image;
    });
});
####dispatch_after
dispatch_after用来延后将操作放入队列。

dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t) (5.0 * NSEC_PER_SEC));
dispatch_after(time, dispatch_get_main_queue(), ^(void) {
[self doSomething];
});

dispatch_after其实就是一个延迟版的 dispatch_async。
其它待续。





相关文章

  • GCD入门(二)啦

    废话不多说,直接从GCD所提供的函数说起。 dispatch_once 相信大家对单例模式可谓是司空见惯了吧,常见...

  • GCD入门

    讲在前面 GCD、NSOperation、NSThread哪个你比较中意呢?我用的GCD很顺手啊,相信很多人也和我...

  • GCD入门

    Grand Central Dispatch(GCD) 是 iOS 开发的一个多核编程的较新的解决方法。它主要用于...

  • GCD 入门

    同步,异步:同步是指:当一个 block 被添加到 queue 时,会阻塞当前运行的线程,直到 block 中的内...

  • iOS实录16:GCD使用小结(二)

    iOS实录16:GCD使用小结(二) iOS实录16:GCD使用小结(二)

  • GCD学习(三)

    GCD学习一 GCD学习二 GCD学习三 常用函数: dispatch_set_target_queue disp...

  • iOS开发多线程篇--GCD

    目录: 一 GCD简介 二 GCD中的队列 三 注意点 一 GCD简介 1 什么是GCD? 全称是Grand Ce...

  • iOS多线程之GCD详解

    原文链接:整理多线程:GCD详解,如有侵权立即删除 一、GCD简介 为什么要用GCD呢? 二、GCD任务和队列 2...

  • GCD入门(二)多核心的性能

    转自此处 概念 为了在单一进程中充分发挥多核的优势,我们有必要使用多线程技术(我们没必要去提多进程,这玩意儿和GC...

  • GCD相关知识点

    GCD相关知识点 多线程技术--GCD 深入学习GCD GCD 深入理解:第一部分 GCD 深入理解:第二部分 1...

网友评论

    本文标题:GCD入门(二)啦

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