iOS 单例模式

单例模式应该是设计模式中很简单的一种,最近项目上有用到,写篇log记录一下

一:什么是单例模式

一个类在全局只允许有一个实例,全局访问的都是这个同一个实例,并且这个实例的生命周期被延长了,这个实例在程序的整个生命周期中都会存在

栗子:

有一个UserModel的类,你需要实例化出来一个对象userModel,在app全局都会用到userModel这个对象,然后你又希望这个userModel一直存在内存中,随时都能拿到里面的内容。这就是一个很好的单例的应用

二:实现单例模式
+ (instancetype)defaultModel;

+ (instancetype)defaultModel {
    static ELUserModel *_instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (_instance == nil) {
            _instance = [[self alloc] init];
        }
    });
    return _instance;
}

用define快速声明单例

#define DECLARE_SINGLETON(method) \
+ (instancetype)method;

#define DEFINE_SINGLETON(clazz, method) \
+ (instancetype)method { \
static clazz *instance = nil; \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
instance = [[clazz alloc] init]; \
}); \
return instance; \
}
三:需要注意的问题

OC语言的构造方法都是公开的,外部还是可以通过alloc init方法构造出新的对象,导致会有多个实例,单例失败。
这个问题有两种解决方案
1:在创建对象的时候哦,无论是alloc或者new都会调用-(id)copyWithZone:(NSZone *)zone,-(id)mutableCopyWithZone:(NSZone *)zone这几个方法
所以我们可以重写这些方法

-(id)copyWithZone:(NSZone *)zone{
    return [ELUserModel defaultModel];
}
-(id)mutableCopyWithZone:(NSZone *)zone{
    return [ELUserModel defaultModel];
}

2:禁用自带的构造方法,告诉使用者,这是一个单例,否则编译不过

+(instancetype) alloc __attribute__((unavailable("call sharedInstance instead")));
+(instancetype) new __attribute__((unavailable("call sharedInstance instead")));
-(instancetype) copy __attribute__((unavailable("call sharedInstance instead")));
-(instancetype) mutableCopy __attribute__((unavailable("call sharedInstance instead")));

你可能感兴趣的:(iOS 单例模式)