正确创建本地单例Obj C.(不是共享的全局单例)

时间:2015-10-20 19:52:22

标签: objective-c singleton

我正在设计一个必须随时只有一个实例的类。我试图避免全局可访问的共享单例的常见模式,我只想要一个只能分配一次但也可以设置为nil的本地对象。这看起来怎么样?

static BOOL isInitialized = NO;

@implementation Single



-(instancetype) init
{
  if (isInitialized == NO)
  {
    if (self = [super init])
    {

    }        
    isInitialized = YES;
    return self;
  }
  else
  {
    NSAssert(FALSE, @"Only one instance allowed");
    return nil;
  }    
}


-(void) dealloc
{
    isInitialized = NO;
}

@end

我不关心线程安全,因为我只打算在主线程上使用class。当对象被推迟时,被覆盖的dealloc应该确保可以创建一个新实例。有人看到这个或改进的任何问题吗?干杯

3 个答案:

答案 0 :(得分:0)

这是一个极端情况,但如果对[super init]的调用失败,那么isInitialized将被设置为YES (请注意,在这种情况下,已通过在self中取消分配之前设置了标志) - 这意味着将不会创建该类的任何实例,因为没有任何内容可以解除分配以重置您的标志。也许你想要:

if (self = [super init])
{
   isInitialized = YES;
}        
return self;

否则,鉴于您不关心线程安全性并且您希望第二次尝试失败(使用NSAssert),您的代码看起来很好。

答案 1 :(得分:0)

返回现有实例而不是崩溃会更好吗?

@implementation Single

- (instancetype)init {
    static __weak Single *weakInstance;

    Single *strongInstance = weakInstance;
    if (strongInstance) {
        self = strongInstance;
    } else {
        if (self = [super init]) {
            weakInstance = self;
        }
    }
    return self;
}

您无需在dealloc中执行任何特殊操作,因为系统将在取消分配实例时自动清除__weak引用。

答案 2 :(得分:0)

@Rob

可以从您的方法中移除强引用吗?

- (instancetype)init
{
    static __weak id weakInstance;

    if (weakInstance)
    {
        self = weakInstance;
    }
    else
    {
        if (self = [super init])
        {
            weakInstance = self;
        }
    }
return self;

}

似乎有效。