有没有办法用objective-c创建一个Singleton模式,这将使客户端代码能够获得任何子类的共享实例?
我试过了:
@interface Base : NSObject {}
+(id)instance;
@end
@implementation Base
static id _instance;
+(id)instance {
if (!_instance) {
_instance = [[self alloc] init];
}
return _instance;
}
@end
但是调用任何子类的[AmazingThing instance]
只返回通过此机制创建的第一个实例,无论_instance
是什么类型。任何干净的解决方法?
修改
我意识到(在回复已删除的答案时)我可以通过更改实施来做我想要的事情:
static NSMutableDictionary *_instances;
+(id)instance {
if (!_instances) {
_instances = [[NSMutableDictionary alloc] init];
}
id instance = [_instances objectForKey:self];
if (!instance) {
instance = [[self alloc] init];
[_instances setObject:instance forKey:self];
}
return instance;
}
它现在按预期工作。不过,我很想知道是否有更好的方法来做到这一点。
答案 0 :(得分:7)
我会这样做:
+(id) instance
{
static id theInstance = nil;
if (theInstance == nil)
{
theInstance = [[self alloc] init];
}
return theInstance;
}
当然,您需要在基类的每个子类中使用该方法,以便为每个类获取不同的静态变量。但是你要在基类头中创建一个#define
:
#define CREATE_INSTANCE \
+(id) instance \
{ \
static id theInstance = nil; \
if (theInstance == nil) \
{ \
theInstance = [[self alloc] init]; \
} \
return theInstance; \
}
然后每个实现只有其中的定义:
@implementation SubClass
CREATE_INSTANCE
// other stuff
@end
答案 1 :(得分:1)
如果使用Objective-C ++就可以了。你可以做的是有一个元编程的C ++类来管理单例对象的生命周期。
这样您就可以使用Singleton模式并使用单例访问单例
Derived* d = Singleton<Derived>::get()
。
如需进一步参考,请查看http://src.chromium.org/viewvc/chrome/trunk/src/base/singleton_objc.h这是chrome如何设法完成的。
答案 2 :(得分:0)
只需使用EPPZSingleton。
创建一个只能有一个子类的基类很简单,但是当你开始创建越来越多的子类时,你可能会发现不需要的行为。 EPPZSingleton通过维护共享的单例集合来解决这个问题。
答案 3 :(得分:0)