如何确保Objective-C中一次只有一个类的实例?

时间:2014-10-31 21:17:22

标签: objective-c singleton retaincount

这与标准singleton pattern略有不同,因为如果对象的所有外部引用都已释放,那么单例也将被释放。然后,稍后,当请求新对象时,将创建新的单例。所以,像这样:

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.

我尝试使用弱静态变量来挂起我的作用域单例,但这不起作用,因为我没有办法增加ARC下的保留计数。这让我感到疑惑:这甚至可能吗?

2 个答案:

答案 0 :(得分:1)

覆盖allocWithZone:管理单个静态实例。如果为nil,则创建一个新的,如果不是nil,则返回它的保留版本。

实现dealloc,当调用nil时,单个静态实例。

我不确定这是否适用于ARC,您可能需要为该文件禁用arc。

保持物体的价格有多贵?按照标准的单身人士模式而忘记它就不那么麻烦了。

答案 1 :(得分:0)

根据@ 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;
    });
}

这假定初始化程序可以处理“脏数据”,如described by Mike Ash