单粒设计模式能为全局提供同一个对象,因此,这个对象只需要创建一次,比如一个应用的登录页面。
示例代码:
//.h
@interface YYCar : NSObject
+ (instancetype)sharedCar;
@end
//.m
@implementation YYCar
// static 限制访问范围只在.m内
static YYCar *_car;
// 该处的alloc方法会触发父类的allocWithZone:方法,
// 为了防止外界直接使用allocWithZone:方法时返回nil,因此需重写该方法
// copyWithZone:方法同理
+ (instancetype)sharedCar
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_car = [[self alloc] init];
});
return _car;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_car = [super allocWithZone:zone];
});
return _car;
}
- (id)copyWithZone:(NSZone *)zone
{
return _car;
}
@end
有追求的程序员应该要想到,这个过程太啰嗦,况且,所有创建单粒的方法都长一个样,升级版的做法是把创建单粒的方法都抽出来,如下(只需要一个.h文件):
#define YYInstanceH + (instancetype)sharedInstance;
#define YYInstanceM \
\
static id _instance; \
\
+ (instancetype)sharedInstance \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[self alloc] init]; \
}); \
return _instance; \
} \
\
+ (instancetype)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [super allocWithZone:zone]; \
}); \
return _instance; \
} \
\
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instance; \
}
更高逼格的改进
上边的方法的确达到了“快、准、狠”的效果,不过,有时候有些场景需要在获取单粒的方法后边使用单粒的名称,就像sharedApplicatioin
一个具体、形象、生动, 传入一个单粒名称即可:
#define YYInstanceH(name) + (instancetype)shared##name;
#define YYInstanceM(name) \
\
static id _instance; \
\
+ (instancetype)shared##name \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[self alloc] init]; \
}); \
return _instance; \
} \
\
+ (instancetype)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [super allocWithZone:zone]; \
}); \
return _instance; \
} \
\
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instance; \
}