在阅读有关Objective C中单例的问题的回答后,似乎每个解决方案在实例访问器的线程方面都做出了一些权衡。即:
@synchronized(self)
{
if (sharedInstance == nil)
sharedInstance = [[MySingleton alloc] init];
}
return sharedInstance;
这实际上是将对单例的访问单线程化,如果在操作中频繁使用它,似乎会导致线程不必要地竞争。
直接使用类对象作为单例实例,并通过类方法公开功能,有什么缺点呢?
@interface MySingleton : NSObject {
}
+ (void)doSomething;
@end
@implementation MySingleton
+ (void)initialize {
//do some setup if necessary
}
+ (void)doSomething {
//do something
}
@end
这样我们就避免了每次引用单例对象时进行锁定+检查的操作,同时也消除了将其存储在本地或方法实例变量中的需要。这种方法还可以让运行时保证系统中任何给定时间只存在一个实例(Class对象)。 编辑 这里不仅涉及到线程处理,对于传统的单例模式,通常会编写以下代码:
MySingleton *instance = [MySingleton getSharedInstance];
NSObject *someResult = [instance getResult];
//or
if (instance.someProperty) {
//do something
}
然而,如果你的单例是类实例,你基本上可以消除一直调用 getSharedInstance 的需要。请考虑以下代码:
NSObject *someResult = [MySingleton getResult];
//or
if ([MySingleton someProperty]) {
//do something
}
我听到的观点是你必须将数据存储在文件本地静态变量或全局变量中(呕吐),但它与传统的单例并没有什么不同,除了失去了Objective-C 2.0属性(相反,您必须使用传统的访问器方法)。
对我来说,这里有一个关键的权衡,似乎是一种胜利。在传统的单例中,如果您真的想要做得正确,最终会覆盖-copyWithZone、+allocWithZone、-retain、-retainCount、-release和-autorelease。
这似乎是每次想编写简单的Singleton对象时都需要做很多工作。那为什么不简单地用这个替换它呢:
@implementation MySingleton
+ (void)initialize {
//do your setup
}
- (id)init {
NSAssert(NO, @"You should read the documentation on singletons.");
}
@end
代码轻量,除非用户非常机智,否则不会创建两个实例。
言归正传 我的问题是:
使用类对象作为单例的实例是否有任何缺点?
似乎可以采取同样的线程安全、内存效率等措施,而不必记住覆盖那么多方法和访问器或在代码中添加实例检查。