Синглтон Реализация. Блокировка методов alloc и init для внешнего использования

У меня есть класс, который я хочу реализовать как Singleton.

Мне бы хотелось, чтобы единственный способ создания экземпляра этого класса был доступен через:

+(MYClass*)sharedInstance 

метод. alloc и init вызываются в реализации метода (конечно).

Есть ли способ заблокировать использование alloc и init или сделать их "пустыми", если есть попытка создать экземпляр этого класса НЕ через метод sharedInstance (но напрямую через alloc + init)?

2 ответа

Размещение этого кода в заголовочном файле должно привести к ошибке времени компиляции, если init вызывается вне реализации:

- (id)init __attribute__((unavailable("cannot use init for this class, use +(MYClass*)sharedInstance instead")));

Я нашел эту технику здесь.

Обновить:

Вы не сможете написать [[MYClass alloc] init] в вашем.m файле, но вы можете использовать следующее:

+ (MYClass *)sharedInstance {
    static MYClass *sharedInstance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [self new];
    });
    return sharedInstance;
}

Если вы используете arc, добавьте флаг компилятора -fno-objc-arc в файл.

"alloc + init" вызовет метод sharedManager.

static MyGizmoClass *sharedGizmoManager = nil;

+ (MyGizmoClass*)sharedManager
{
    if (sharedGizmoManager == nil) {
        sharedGizmoManager = [[super allocWithZone:NULL] init];
    }
    return sharedGizmoManager;
}

+ (id)allocWithZone:(NSZone *)zone
{
    return [[self sharedManager] retain];
}

- (id)copyWithZone:(NSZone *)zone
{
    return self;
}

- (id)retain
{
    return self;
}

- (NSUInteger)retainCount
{
    return NSUIntegerMax;  //denotes an object that cannot be released
}

- (void)release
{
    //do nothing
}

- (id)autorelease
{
    return self;
}
Другие вопросы по тегам