我正在设计一个必须随时只有一个实例的类。我试图避免全局可访问的共享单例的常见模式,我只想要一个只能分配一次但也可以设置为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应该确保可以创建一个新实例。有人看到这个或改进的任何问题吗?干杯
答案 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;
}
似乎有效。