Para sincronizar la creación de singleton, debe usar la clase singleton como el objeto para sincronizar. Este es mi patrón habitual:
+(MyObject*) singleton
{
static MyObject* singleton = nil;
@synchronized([MyObject class])
{
if(singleton == nil)
{
singleton = [[MyObject alloc] init];
}
}
return singleton;
}
Puntos a tener en cuenta:
He dejado un método de clase. En realidad no tienes que hacerlo, funcionará como un método de instancia.
Normalmente, en los métodos de clase cuando se hace referencia a la clase, debe usar self
(o [self class]
en métodos de instancia). Sin embargo, eso sería incorrecto porque las subclases se sincronizarían usando un objeto diferente a la clase MyObject.
He puesto la devolución fuera del bloque @synchronize
. Está perfectamente bien regresar desde el interior del bloque, pero si lo haces, recibes una advertencia falsa del analizador estático clang diciendo que el método podría no devolver un valor.
Editar
El patrón anterior es obsoleto desde hace mucho tiempo. Lo mejor es usar
+(MyObject*) singleton
{
static dispatch_once_t onceToken;
static MyObject* singleton = nil;
dispatch_once (&onceToken, ^{
singleton = [[MyObject alloc] init];
});
return singleton;
}
duplicado http://stackoverflow.com/questions/1215330/how-does-synchronized-lock-unlock-in-objective-c –
No es exactamente un duplicado, una pregunta relacionada con el patrón
dispatch_once
Por supuesto. –