Строго говоря, вы должны использовать:
+ (MySingleton*) instance {
static dispatch_once_t _singletonPredicate;
static MySingleton *_singleton = nil;
dispatch_once(&_singletonPredicate, ^{
_singleton = [[super allocWithZone:nil] init];
});
return _singleton;
}
+ (id) allocWithZone:(NSZone *)zone {
return [self instance];
}
Теперь вы гарантируете, что нельзя вызывать alloc / init и создать другой экземпляр.
Объяснение: Метод экземпляра находится на уровне классаи ваш основной метод доступа, чтобы получить ссылку на синглтон.Метод просто использует встроенную очередь dispatch_once (), которая будет выполнять блок только один раз.Как среда выполнения гарантирует, что блок выполняется только один раз?Используя предоставленный вами предикат (типа dispatch_once_t).Этот низкоуровневый вызов гарантирует, что даже если есть несколько потоков, пытающихся вызвать его, успешным будет только один, остальные ждут, пока первый не будет выполнен, а затем возвращаются.
Причина, по которой мы переопределяем allocWithZone, заключается в том, что allocвызывает allocWithZone, передавая nil как зону (для зоны по умолчанию).Чтобы не допустить мошеннического кода для выделения и инициализации другого экземпляра, мы переопределяем allocWithZone, чтобы передаваемый экземпляр был уже инициализированным синглтоном.Это препятствует созданию второго экземпляра.