关于GCD中单例的实现,不仅仅是 dispatch_once(视图完整版)

时间:2022-08-14 20:47:57

之前太过于年轻,总结的简单单例模式传送门: http://www.cnblogs.com/PSSSCode/p/5482419.html

这篇博客主要讲的是GCD中的单例模式,大家肯定会想到dispatch_once这个函数,但是这篇博客不仅仅是dispatch_once的使用。

1、单例模式简介(面试常考的。。。)

  • 单例模式的作用
    • 可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问
    • 从而方便地控制了实例个数,并节约系统资源
  • 单例模式的使用场合  
    • 系统  
      • UIApplication、NSUserDefaults、NSFileManager、NSNoticationCenter 
    • 自定义
      • 在某个应用程序中,共享一份资源(这份资源只需要创建初始化一次)
      • 网络计数器
      • 分享界面、登录界面、评论界面不登录会跳转到唯一界面登录界面(单例实现)
      • 点击跳转,控制器设置为单例,该控制器不会被销毁,依然存在内存中,返回再次回去,再点击进来,则会快速进入不会创建对应的新的控制器

2、具体代码

  • 只需实现三个方法
    • 1、allocWithZone:       (alloc底层调用该方法)
    • 2、shareCar          (一种命名规范)
    • 3、copyWithZone      (对应实例变量 调用copy会调用该方法)

默认情况

关于GCD中单例的实现,不仅仅是 dispatch_once(视图完整版)

添加单例情况

 1 @interface PSSCar() // <NSCopying>
 2 
 3 @end
 4 
 5 @implementation PSSCar
 6 
 7 static PSSCar *_car;
 8 
 9 + (instancetype)allocWithZone:(struct _NSZone *)zone
10 {
11     static dispatch_once_t onceToken;
12     dispatch_once(&onceToken, ^{
13         _car = [super allocWithZone:zone];
14     });
15     return _car;
16 }
17 
18 + (instancetype)sharedCar
19 {
20     static dispatch_once_t onceToken;
21     dispatch_once(&onceToken, ^{
22         _car = [[self alloc] init];
23     });
24     return _car;
25 }
26 
27 - (id)copyWithZone:(NSZone *)zone
28 {
29     return _car;
30 }

 关于GCD中单例的实现,不仅仅是 dispatch_once(视图完整版)

3、封装代码

当一个项目中多个类需要使用单例,则需要在对应类的.m文件中写以上的代码,并且代码几乎没有差别,所有可以将上面的代码封装成一个工具类,并在工具类中使用宏定义,减少代码冗余。

// .h文件
#define PSSSingletonH(name) + (instancetype)shared##name;

// .m文件
#define PSSSingletonM(name) \
static id _instance; \
 \
+ (instancetype)allocWithZone:(struct _NSZone *)zone \
{ \
    static dispatch_once_t onceToken; \
    dispatch_once(&onceToken, ^{ \
        _instance = [super allocWithZone:zone]; \
    }); \
    return _instance; \
} \
 \
+ (instancetype)shared##name \
{ \
    static dispatch_once_t onceToken; \
    dispatch_once(&onceToken, ^{ \
        _instance = [[self alloc] init]; \
    }); \
    return _instance; \
} \
 \
- (id)copyWithZone:(NSZone *)zone \
{ \
    return _instance; \
}

 

在对应类的.h和.m中只需要调用宏定义重新命名的响应方法即可,同时将本类的类名传入,即可实现快速单例模式的实现与使用