• (一二三)基于GCD的dispatch_once实现单例设计


    要实现单例,关键是要保证类的alloc和init只被调用一次,并且被自身强引用防止释放。

    近日读唐巧先生的《iOS开发进阶》,受益匪浅,通过GCD实现单例就是收获之一,下面把这个方法与大家分享。

    在GCD中,有一个函数dispatch_once,可以实现代码段的一次性执行,和static修饰的变量赋值的一次性一样,我们结合static和dispatch_once,就可以简单的实现单例。

    下面的代码实现了SomeClass单例:

    #import <Foundation/Foundation.h>
    
    @interface SomeClass : NSObject
    
    + (SomeClass *)sharedInstance;
    
    @end
    #import "SomeClass.h"
    
    @implementation SomeClass
    
    + (SomeClass *)sharedInstance{
        
        static id sharedInstance = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            sharedInstance = [[self alloc] init];
        });
        
        return sharedInstance;
        
    }
    
    @end
    下面解释一下这段代码。

    第一句新建一个sharedInstance静态强指针,是为了指向创建好的单例,防止其释放,只有第一次进入的时候指针被赋值为nil。

    一定注意dispatch_once_t变量必须是静态,它的值用于判断是否已经执行一次

    第二句和dispatch_once是固定用法,这样可以实现block内的代码一次性执行,也就是说只有第一次调用这个方法时才会实例化类,之后都是返回指针指向的值。

    最后返回指针,就相当于拿到了单例。


    对单例的运行结果进行验证:

    我们多次获取单例对象并且打印地址,可以发现地址是一样的。

    #import "ViewController.h"
    #import "SomeClass.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        SomeClass *sc1 = [SomeClass sharedInstance];
        SomeClass *sc2 = [SomeClass sharedInstance];
        SomeClass *sc3 = [SomeClass sharedInstance];
        NSLog(@"%p %p %p",sc1,sc2,sc3);
        
    }
    
    @end
    2015-08-17 20:59:22.139 基于GCD实现单例[2785:31918] 0x7fb40af11b90 0x7fb40af11b90 0x7fb40af11b90

    通过这种方式,简单高效的实现了单例,值得使用。

  • 相关阅读:
    BeanFactory not initialized or already closed
    点击程序不弹出界面,但有后台服务
    python获取一年所有的日期
    keepalived实现高可用
    解决docker镜像pull超时问题
    docker容器的操作
    docker小结
    docker概述
    docker镜像操作
    python批量下载
  • 原文地址:https://www.cnblogs.com/aiwz/p/6154049.html
Copyright © 2020-2023  润新知