如何实现与ARC兼容的Objective-C单例?

ces*_*fry 168 singleton objective-c ios automatic-ref-counting

在Xcode 4.2中使用自动引用计数(ARC)时,如何转换(或创建)编译和行为正确的单例类?

Nic*_*rge 378

完全一样,你(应该)已经这样做了:

+ (instancetype)sharedInstance
{
    static MyClass *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[MyClass alloc] init];
        // Do any other initialisation stuff here
    });
    return sharedInstance;
}
Run Code Online (Sandbox Code Playgroud)

  • 那是因为他正在使用ARC.完全正确的答案. (30认同)
  • 你只是不做苹果过去在http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html#//apple_ref/推荐的任何内存管理工具. DOC/UID/TP40002974-CH4-SW32 (9认同)
  • 如果有人调用[[MyClass alloc] init]怎么样?这将创建一个新对象.我们怎样才能避免这种情况(除了在方法外声明静态MyClass*sharedInstance = nil). (9认同)
  • 在方法/函数中声明的@David`static`变量与在方法/函数外声明的`static`变量相同,它们仅在该方法/函数的范围内有效.通过`+ sharedInstance`方法(即使在不同的线程上)的每次单独运行都将"看到"相同的`sharedInstance`变量. (6认同)
  • 如果另一个程序员搞砸了,当他们应该调用sharedInstance或者类似的东西时调用init,那就是他们的错误.颠覆语言的基本原理和基本合同,以阻止其他人潜在地犯错,这似乎是错误的.有关http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong的更多讨论 (2认同)

Don*_*gXu 8

如果你想根据需要创建其他实例.这个:

+ (MyClass *)sharedInstance
{
    static MyClass *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[MyClass alloc] init];
        // Do any other initialisation stuff here
    });
    return sharedInstance;
}
Run Code Online (Sandbox Code Playgroud)

否则,你应该这样做:

+ (id)allocWithZone:(NSZone *)zone
{
    static MyClass *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [super allocWithZone:zone];
    });
    return sharedInstance;
}
Run Code Online (Sandbox Code Playgroud)

  • @Olie:错误,因为客户端代码可以执行`[[MyClass alloc] init]`并绕过`sharedInstance`访问.DongXu,你应该看[Peter Hosey的Singleton文章](http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong).如果你要覆盖`allocWithZone:`以防止创建更多实例,你也应该覆盖`init`以防止重新初始化共享实例. (4认同)
  • 这完全打破了allocWithZone的合同. (2认同)

Igo*_*gor 5

这是ARC和非ARC的版本

如何使用:

MySingletonClass.h

@interface MySingletonClass : NSObject

+(MySingletonClass *)sharedInstance;

@end
Run Code Online (Sandbox Code Playgroud)

MySingletonClass.m

#import "MySingletonClass.h"
#import "SynthesizeSingleton.h"
@implementation MySingletonClass
SYNTHESIZE_SINGLETON_FOR_CLASS(MySingletonClass)
@end
Run Code Online (Sandbox Code Playgroud)