EDIT
Я в том числе это сверху, ниже вы можете увидеть мои исторические оригинальные вопросы и реализации.Однако я думаю, что я нашел оптимальный способ обеспечить способ sharedInstance без каких-либо стопорного над головой, я хотел бы услышать потенциальные проблемы по этому поводу:
// Volatile to make sure we are not foiled by CPU caches
static volatile ALBackendRequestManager *sharedInstance;
// There's no need to call this directly, as method swizzling in sharedInstance
// means this will get called after the singleton is initialized.
+ (MySingleton *)simpleSharedInstance
{
return (MySingleton *)sharedInstance;
}
+ (MySingleton*)sharedInstance
{
@synchronized(self)
{
if (sharedInstance == nil)
{
sharedInstance = [[MySingleton alloc] init];
// Replace expensive thread-safe method
// with the simpler one that just returns the allocated instance.
SEL orig = @selector(sharedInstance);
SEL new = @selector(simpleSharedInstance);
Method origMethod = class_getClassMethod(self, orig);
Method newMethod = class_getClassMethod(self, new);
method_exchangeImplementations(origMethod, newMethod);
}
}
return (MySingleton *)sharedInstance;
}
И историческая дискуссия вокруг инициализации:
I теперь исходный код был скорее похож на мой (ниже), за исключением проверки экземпляра вне блокировки.
Хотя новый метод инициализации + (void) интересен, я не уверен, что мне это лучше нравится. Кажется, что теперь вы можете получить экземпляр singleton, который вы должны всегда звонить:
MySingleton instance = [[MySingleton alloc] init];
Неверное ли это? Это странно, и эффективнее, если вызов для инициализации уже заблокирован для вас? Метод двойной блокировки, похоже, работает нормально для этого варианта использования, а также избегает блокировки (при потенциальной стоимости двойного размещения я думаю, так как более чем один поток может провалиться через if).
Другое, что кажется странным, если, если метод initialize был действительно предпочтительным, почему мы не видим его в другом месте? Objective-C работает в течение долгого времени, и я опасаюсь основополагающих механизмов, которые отличаются от практически всех опубликованных примеров.
Мой код, который я в настоящее время использую (который отражает, что я видел в других местах, в том числе this ответ):
+ (MySingleton *)sharedInstance
{
@synchronized(self)
{
if (sharedInstance == nil)
sharedInstance = [[MySingleton alloc] init];
}
return sharedInstance;
}
+ (id)allocWithZone:(NSZone *)zone
{
@synchronized(self)
{
if (sharedInstance == nil)
{
sharedInstance = [super allocWithZone:zone];
return sharedInstance; // assignment and return on first allocation
}
}
return nil; // on subsequent allocation attempts return nil
}
Пожалуйста, не изменяйте свой вопрос таким образом, чтобы существующие ответы были недействительными или больше не релевантными. – dreamlax
Почему еще одна цепочка Objective-C singleton? См. Http://stackoverflow.com/questions/145154 для примера. – zoul
Не могли бы вы просто использовать Gallagher's. Http://projectswithlove.com/projects/SynthesizeSingleton.h.zip от http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html. ..? – Fattie