Heim > Fragen und Antworten > Hauptteil
网站普遍的创建单例类的方法有下面两种:
+ (instancetype)sharedManager {
static id _sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedInstance = [[self alloc] init];
});
return _sharedInstance;
}
+ (instancetype)sharedManager {
static id _sharedInstance = nil;
@synchronized(self) {
if (_sharedInstance == nil)
_sharedInstance = [[self alloc] init];
}
return _sharedInstance;
}
但是该如何避免意外的用[[alloc] init]
创建呢?主要是发现网上找到的大多仅仅只有上面的代码,少有考虑被init
或者copy
的情况
黄舟2017-04-18 09:43:01
又去stackovweflow找了下方法,我觉得既然是单例模式,调用者就应该严格按照单例的要求,通过统一的接口(这里是sharedInstance)去创建单例,而不应该出现调用[[class alloc] init]也能成功创建单例的情况,如果出现[[class alloc] init]的情况,我觉得更应该让Xcode给出警告不能用此方法
- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;
迷茫2017-04-18 09:43:01
覆盖allocWithZone和copyWithZone方法。
因为通过alloc或者copy还是new,都是通过调用allocWithzone和copyWithzone来分配空间的。
你可以把sharedManager 方法里面的代码写到这两个方法里面,就可以从根本实现了单例的情况
大家讲道理2017-04-18 09:43:01
(instancetype)init {
@throw [NSException exceptionWithName:@"Disable" reason:@"Please use init instead..." userInfo:nil];
return self;
}
天蓬老师2017-04-18 09:43:01
这样写就可以了
static Singleton *slt = nil;
+ (instancetype)sharedInstance{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
slt = [[self alloc]init];
});
return slt;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
slt = [super allocWithZone:zone];
});
return slt;
}
- (id)copyWithZone:(NSZone *)zone
{
return slt;
}