Используйте Singleton In Interface Builder?
У меня синглтон настроен так:
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
метод.
2 ответа
Это можно сделать. Об этом есть раздел в " Какао-дизайне " Бака и Яхтмана.
В вашем случае вы могли бы сделать что-то вроде:
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;
}
Код загрузки пера тогда правильно подберет синглтон через его вызов [[Universe alloc] init]
и вы все еще можете использовать instance
в вашем коде, как и раньше.
Книга содержит более подробную информацию и рекомендует реализацию new
а также allocWithZone
(оба просто как return [self alloc];
), а также заглушки сообщения об ошибках, чтобы поймать copyWithZone
а также mutableCopyWithZone
попытки для хорошей меры.
Это будет течь. Вы можете сойти с рук, если вы измените его на:
if(instance) {
[self release];
return instance;
}
но это все еще пахнет немного для меня. Мне любопытно, что вы используете для одиночных игр в IB; Я подозреваю, что я бы избежал этой конструкции в моем коде.