differenza tra queste due implementazioni di iniziatori thread-safe nell'objective C

Quindi ho un singleton e sto cercando di capire la differenza tra queste due implementazioni: funzionalmente ho provato a eseguire il mio codice con entrambi e entrambi funzionano

Tuttavia, noto che nella prima implementazione non è stato chiamato [self alloc], ma la chiamata è a [super allocazione]. Sono un po 'perplesso da questo. Sembra funzionare ma sembra un po 'magico quindi mi chiedo se qualcuno può chiarire

1o modo:

+(id)getSingleton { static dispatch_once_t pred; dispatch_once(&pred, ^{ locMgrSingleton = [[super alloc] init]; }); return locMgrSingleton; } 

Un altro modo

  +(id)getSingleton { @synchronized(self) { if (locMgrSingleton == nil) { locMgrSingleton = [[self alloc]init]; NSLog(@"Created a new locMgrSingleton"); } else { NSLog(@"locMgrSingleton exists"); } } return locMgrSingleton; } 

Solutions Collecting From Web of "differenza tra queste due implementazioni di iniziatori thread-safe nell'objective C"

L'utilizzo di [self alloc] vs [super alloc] non fa differenza a less che la class non sovrascriva +alloc . Detto questo, dovrebbe call [self alloc] . Scommetto che sta chiamando super perché probabilmente è stato adattato da un'implementazione che sovrascrive +alloc per restituire un singleton.

In each caso, la differenza tra i due pattern, oltre a self vs super , è spiegata nella mia risposta a questa altra domanda , ma in breve, dispatch_once() è il modo moderno per farlo. È più veloce di @synchronized e ha un significato più semantico.

Come detto ad esempio su http://cocoasamurai.blogspot.fi/2011/04/singletons-your-doing-them-wrong.html , la chiamata di dispatch_once sembra essere un po 'più veloce di @synchronized(self) .

Per quanto riguarda il motivo per cui [super alloc] invece di [self alloc] , non vedo alcun motivo per cui si applicherebbe specificamente alla versione di dispatch_once ma non a quella dell'altro. In un metodo statico, self si riferisce semplicemente alla class stessa (e super alla sua superclass diretta), e io la vedrei come una scorciatoia per scrivere il vero nome della class, niente di più.

Ho sempre usato [self alloc] se, comunque, avrei scritto il nome della class attuale, non la sua superclass. Non ho idea se call specificamente [super alloc] abbia un significato speciale.

In un metodo di class, l' self punta alla class stessa. In entrambe le implementazioni, [self alloc] , [MySingleton alloc] e [super alloc] sono tutti semanticamente equivalenti, a less che per qualche strana ragione non si sovrascrivi +alloc .

Un motivo per cui potresti voler usare [super alloc] rispetto ad altri è quando contrassegni esplicitamente +alloc non disponibile nella tua dichiarazione con una direttiva del compilatore:

+(instancetype) alloc __attribute__((unavailable("alloc not available")));

o

+(instancetype) alloc NS_UNAVAILABLE;

Altrimenti, il compilatore genererà un errore quando +alloc a +alloc un'istanza della tua class singleton, che di solito è ciò che vuoi eccetto quando tu +alloc un'istanza singleton condivisa in dispatch_once.