以前写单利一直这样写:
+ (instancetype)sharedManager {staticid_sharedInstance =nil;staticdispatch_once_tonceToken;dispatch_once(&onceToken, ^{ _sharedInstance = [[selfalloc] init]; });return_sharedInstance;}
或者这样写:
+ (instancetype)sharedManager {staticid_sharedInstance =nil;@synchronized(self) {if(_sharedInstance ==nil) _sharedInstance = [[selfalloc] init]; }return_sharedInstance;}
大概某些时刻也想过在多线程中同时会访问会不会返回两个不同单利,第二种写法也许会更安全一些。
今天一个写C++,业余搞oc(此处说明iOS很好入门呢。。。)的朋友问我如何避免被人调用了alloc 或者 new 甚至copy的情况下,仍保证单利的唯一性呢?
对啊,别人不按套路出牌我们是不是就束手无策了?显然不是,程序员就应该写出尽量安全的代码,百度了几种方法。
1.让xcode 给出警告(有些人就是不爱看警告,你能怎样?)
- (instancetype)initNS_UNAVAILABLE;
+ (instancetype)newNS_UNAVAILABLE;
2.抛出异常(这对于新手来说简直是不友好的办法)
(instancetype)init {
@throw [NSException exceptionWithName:@"Disable" reason:@"Please use init instead..." userInfo:nil];
return self;
}
3.覆盖allocWithZone和copyWithZone方法。
因为通过alloc或者copy还是new,都是通过调用allocWithzone和copyWithzone来分配空间的。
你可以把sharedManager 方法里面的代码写到这两个方法里面,就可以从根本实现了单例的情况
static Singleton *slt= nil;+ (instancetype)sharedInstance{staticdispatch_once_tonceToken;dispatch_once(&onceToken,^{slt= [[self alloc]init];});returnslt;}+ (instancetype)allocWithZone:(struct_NSZone *)zone{ staticdispatch_once_tonceToken;dispatch_once(&onceToken,^{slt= [super allocWithZone:zone];});returnslt;}- (id)copyWithZone:(NSZone *)zone{ returnslt;}
总结:写代码,多考虑一些情况总是好的,不要觉得麻烦或者啰嗦,总比出现了问题辛苦改bug来得强,更推荐第三种方法,因为对于敢于用 alloc 或者new 来创建单利的人,你还指望他会认真看警告或者异常??