我正在写一个单例类,我通常会这样做:
@interface MySingleton
+ (instancetype) instance;
@end
@implementation MySingleton
+ (instancetype) instance {
static MySingleton *instance;
if (!instance) {
instance = [MySingleton new];
}
return instance;
}
@end
但我最近考虑过这种模式:
@interface MySingleton
+ (instancetype) instance;
@end
@implementation MySingleton
static MySingleton *instance;
+ (void) load {
instance = [MySingleton new];
}
+ (instancetype) instance {
return instance;
}
@end
我发现这更优雅,更容易理解,但这将是我第一次使用+load
。 我有没有陷入任何陷阱?有什么理由这是个坏主意吗?
答案 0 :(得分:3)
+load
。虽然现有的ObjC代码仍然会执行它(即使从Swift调用),新代码也不应该依赖它。 @ gnasher729引用的dispatch_once
方法是强烈优选的,并且具有延迟的优点(+load
减慢启动速度; dispatch_once
在第一次使用之前不强制构造)。 dispatch_once
Singleton甚至是Xcode中的内置代码片段。 Apple在Adopting Cocoa Design Patterns中提供了推荐的实现。
+ (instancetype)sharedInstance {
static id _sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedInstance = [[self alloc] init];
});
return _sharedInstance;
}
(或在斯威夫特)
class Singleton {
static let sharedInstance = Singleton()
}
sharedInstance
的命名sharedFoo
(或更好,Foo
的{{1}})优先于instance
。请参阅+[NSURLSesssion sharedSession]
等。这将捕获ObjC中单身人士的真实本质,而不是真正单身人士。只有一个众所周知的例子。您通常可以使用+new
或+alloc
自由实例化其他实例。 +instance
听起来像+new
一样,创建一个新的实例。 +sharedInstance
清楚地表明这是其他呼叫者共享的实例。
作为附注,我提到近年来ObjC社区中的许多人gradually moving away from singletons因为他们在测试中创造的困难,他们创建全球可变状态以及一般缺乏灵活性。手动依赖注入(即仅设置属性或传递参数,而不是复杂的DI框架)一直在增长。这远非普遍,我并没有声称Singleton是ObjC中的反模式,但我鼓励你避免使用Singleton,因为它不是一个巨大的好处。多年来,它是我解决许多问题的首选方案,但时间和模式都有所改变。
答案 1 :(得分:1)
有一种广泛使用的模式来使用dispatch_once创建单例。绝对没有理由为什么有人会以任何不同的方式创建一个单身人士。相反,你想要使用一些非常模糊的技术(例如,一旦你切换到Swift,它就不起作用)。
顺便说一下,尝试调用一些类方法来配置你的单例,然后再创建它。不能用+ load工作。
顺便说一下,你通常的方式"不是线程安全的。