如何正确实现ARC兼容和`alloc init`安全的Singleton类?

Dul*_*gon 8 singleton objective-c ios automatic-ref-counting

我看到了线程安全的版本

+(MyClass *)singleton {
    static dispatch_once_t pred;
    static MyClass *shared = nil;

    dispatch_once(&pred, ^{
        shared = [[MyClass alloc] init];
    });
     return shared;
}
Run Code Online (Sandbox Code Playgroud)

但如果有人打电话[MyClass alloc] init]会怎么样?如何让它返回与+(MyClass *)singleton方法相同的实例?

Jon*_*hon 12

Apple建议使用严格的单例实现(不允许使用相同类型的其他生物对象):

+ (instancetype)singleton {
    static id singletonInstance = nil;
    if (!singletonInstance) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            singletonInstance = [[super allocWithZone:NULL] init];
        });
    }
    return singletonInstance;
}

+ (id)allocWithZone:(NSZone *)zone {
    return [self singleton];
}

- (id)copyWithZone:(NSZone *)zone {
    return self;
}
Run Code Online (Sandbox Code Playgroud)

链接到Apple 文档(页面底部,没有ARC)