我有一个像这样的单身人士设置:
static Universe *instance;
+ (Universe *)instance { return instance; }
+ (void)initialize
{
static BOOL initialized = NO;
if(!initialized)
{
initialized = YES;
instance = [[Universe alloc] init];
}
}
- (id) init
{
self = [super init];
if (self != nil) {
self.showHistory = YES;
}
return self;
}
但现在我意识到我想从Interface Builder中实例化它。我在考虑切入init
这样的方法
if (instance)
return instance;
这是一个坏主意吗?我希望IB选择已在+initialize
方法中创建的实例。
答案 0 :(得分:6)
这可以做到。 Buck和Yachtman在 Cocoa Design Patterns 中有一节介绍它。
在您的情况下,您可以采取以下措施:
static Universe *instance;
+ (Universe *)instance { return instance; }
+ (id)hiddenAlloc
{
return [super alloc];
}
+ (id)alloc
{
return [[self instance] retain];
}
+ (void)initialize
{
static BOOL initialized = NO;
if(!initialized)
{
initialized = YES;
instance = [[Universe hiddenAlloc] init];
}
}
- (id)init
{
if(instance==nil) // allow only to be called once
{
// your normal initialization here
}
return self;
}
然后,nib加载代码会通过调用[[Universe alloc] init]
来正确选取单例,您仍然可以像以前一样在代码中使用instance
。
本书提供了更多详细信息,建议实施new
和allocWithZone
(简称为return [self alloc];
),以及错误报告存根以捕获copyWithZone
和{{1}试图采取良好措施。
答案 1 :(得分:1)
那会泄漏。如果将其更改为:
,则可以使用它if(instance) {
[self release];
return instance;
}
但它仍然闻到了一点味道。我很好奇你对IB中的单身人士有什么用处;我怀疑我会在代码中避免这种构造。