这与标准的singleton模式略有不同,因为如果对对象的所有外部引用都已释放,那么singleton也将被释放。然后,稍后,当请求一个新对象时,将创建一个新的单例。所以,像这样的东西:
MyThing *thing1 = [MyThing new];
MyThing *thing2 = [MyThing new];
// thing1 & thing2 are the same object.
thing1 = nil;
thing2 = nil;
thing1 = [MyThing new];
thing2 = [MyThing new];
// thing1 and thing2 are a the same objet, but it's a different object than above.
我试图使用一个弱静态变量来挂起我的作用域singleton,但没有成功,因为我没有办法在ARC下增加retain计数。这让我想知道:这可能吗?
覆盖allocWithZone:以管理单个静态实例。如果为零,则生成一个新的,如果不是零,则返回其保留版本。
实现dealloc,当调用nil时,实现单个静态实例。
我不确定这是否适用于ARC,您可能需要禁用该文件的ARC。
把这个东西放在身边有多贵?遵循标准的单例模式并忘记它当然不会那么麻烦。
根据@KirkSpaziani的回答,我得出了以下结论:
static __weak MyTHing *currentThing = nil;
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
__block id thing = nil;
dispatch_sync(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (currentThing == nil) {
currentThing = thing = [super allocWithZone:zone];
} else {
thing = currentThing;
}
});
return thing;
}
- (void)dealloc {
dispatch_sync(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
currentThing = nil;
});
}
这假设初始化器可以处理"脏数据",正如Mike Ash所描述的那样。