大数据

正确认识单例模式

文艺求关注.png

啊喂,你遇到面试官要求你手写单例模式了吗?那对于单例模式,你还记得多少?

  • 单例模式的作用

    • 可以保证在程序运行过程中,一个类只有一个实例,而且该实力易于供外界访问
    • 方便控制实例个数,节约系统资源
  • 单例模式的使用场景

    • 在整个应用中,共享一份资源(这份资源只需要创建初始化1次)
  • ARC环境下的单例模式

//.h文件
// 对外爆露类方法
// 原因:1.方便外部调用使用
//      2.为了表明身份
// 注意命名规范:shar + 类名 / default + 类名 / share / default
+ (instancetype) shareTools;

// .m文件
// 1.提供全局变量
static VtcTools *_instance;
// 2.从写alloc方法 --> allocWithZone
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
  • 第一种方法
    // 加互斥锁解决多线程访问安全问题
    @synchronized (self) {
        if (_instance == nil) {
            _instance = [super allocWithZone:zone]; // 外界调用:VtcTools *t1 = [[VtcTools alloc] init];
        }
    }
  • 第二种方法
    // 一次性函数,本身就是线程安全的
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone]; // 外界调用:VtcTools *t2 = [[VtcTools alloc] init];
    });
    return _instance;
}
// 3.提供类方法
+ (instancetype)shareTools {

    return [[self alloc] init]; // 外界调用:VtcTools *t3 = [VtcTools shareTools];
}
// 4.严谨写法(从写以下两种方法)
- (id)copyWithZone:(NSZone *)zone {

    return _instance;   // 外界调用方法:VtcTools *t4 = [t1 copy];
}

- (id)mutableCopyWithZone:(NSZone *)zone {

    return _instance;   // 外界调用方法:VtcTools *t5 = [t1 mutableCopy];
}
  • MRC环境下的单例模式
// 修改环境 --> Build Settings (search) automatic A...R....C...  NO
//.h文件
// 对外爆露类方法
// 原因:1.方便外部调用使用
//      2.为了表明身份
// 注意命名规范:shar + 类名 / default + 类名 / share / default
+ (instancetype) shareTools;
//.m文件
// 1.提供全局变量
static VtcTools *_instance;
// 2.从写allocWithZone方法
+ (instancetype)allocWithZone:(struct _NSZone *)zone {

    // 第一种方法
    // 加互斥锁解决多线程访问安全问题
    @synchronized (self) {
        if (_instance == nil) {
            _instance = [super allocWithZone:zone]; // 外界调用:VtcTools *t1 = [[VtcTools alloc] init];
        }
    }

    // 第二种方法
    // 本身就是线程安全的
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone]; // 外界调用:VtcTools *t2 = [[VtcTools alloc] init];
    });
    return _instance;
}
// 3.提供类方法
+ (instancetype)shareTools {

    return [[self alloc] init]; // 外界调用:VtcTools *t3 = [VtcTools shareTools];
}
// 4.严谨写法(从写以下两种方法)
- (id)copyWithZone:(NSZone *)zone {

    return _instance;   // 外界调用方法:VtcTools *t4 = [t1 copy];
}

- (id)mutableCopyWithZone:(NSZone *)zone {

    return _instance;   // 外界调用方法:VtcTools *t5 = [t1 mutableCopy];
}
#if __has_feature(objc_arc)
// 条件满足ARC
#else
// MRC
- (oneway void)release {
}

- (instanceytpe)retain {
}
// 习惯性重写
- (NSUInteger) retainCont {

    return MAXFLOAT;
}
#endif

!!注意:在使用中,记得retain一次,就需要release一次~

!!注意:单例模式是不能使用继承的
// 单例模式通用宏
//新建.h文件:Singleton
#define SingletonH(name) + (instancetype) share##name;
#if __has_feature(objc_arc)
// 条件满足ARC
#define SingletonM(name) static VtcTools *_instance;    \
+ (instancetype)allocWithZone:(struct _NSZone *)zone {  \
    static dispatch_once_t onceToken;   \
    dispatch_once(&onceToken, ^{    \
        _instance = [super allocWithZone:zone];     \
    }); \
    return _instance;   \
}   \
+ (instancetype)share##name {    \
    return [[self alloc] init]; \
}   \
- (id)copyWithZone:(NSZone *)zone { \
    return _instance;   \
}   \
- (id)mutableCopyWithZone:(NSZone *)zone {  \
    return _instance;   \
}
#else
// MRC
#define SingletonM(name) static VtcTools *_instance;    \
+ (instancetype)allocWithZone:(struct _NSZone *)zone {  \
    static dispatch_once_t onceToken;   \
    dispatch_once(&onceToken, ^{    \
        _instance = [super allocWithZone:zone];     \
    }); \
    return _instance;   \
}   \
+ (instancetype)share##name {    \
    return [[self alloc] init]; \
}   \
- (id)copyWithZone:(NSZone *)zone { \
    return _instance;   \
}   \
- (id)mutableCopyWithZone:(NSZone *)zone {  \
    return _instance;   \
}   \
- (oneway void)release {    \
}   \
- (instanceytpe)retain {    \
}   \
- (NSUInteger) retainCont { \
    return MAXFLOAT;\
}
#endif
// 外界调用:
  //  .h #import "Singleton.h"
      // SingletonH  (输入name)
  //  .m  SingletonM  (输入name)

关注一下又不会怀孕.png