172 votos

¿Cómo implemento un singleton Objective-C que es compatible con el arco?

¿Cómo convertir (o crear) una clase singleton que compila y se comporta correctamente cuando se utiliza la referencia automática contando (ARC) en Xcode 4.2?

394voto

Nick Forge Puntos 13758

En la misma forma que lo (debe) han estado haciendo ya:

+ (MyClass *)sharedInstance
{
    static MyClass *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[MyClass alloc] init];
        // Do any other initialisation stuff here
    });
    return sharedInstance;
}

8voto

DongXu Puntos 152

Si desea crear otra instancia como needed.do esto:

+ (MyClass *)sharedInstance
{
    static MyClass *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[MyClass alloc] init];
        // Do any other initialisation stuff here
    });
    return sharedInstance;
}

Si no, debes hacer esto:

+ (id)allocWithZone:(NSZone *)zone
{
    static MyClass *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [super allocWithZone:zone];
    });
    return sharedInstance;
}

5voto

Igor Fedorchuk Puntos 2936

Esta es una versión para el arco y no-ARC

Cómo utilizar:

MySingletonClass.h

@interface MySingletonClass : NSObject

+(MySingletonClass *)sharedInstance;

@end

MySingletonClass.m

#import "MySingletonClass.h"
#import "SynthesizeSingleton.h"
@implementation MySingletonClass
SYNTHESIZE_SINGLETON_FOR_CLASS(MySingletonClass)
@end

2voto

Eonil Puntos 19404

Este es mi patrón bajo el arco. Satisface el nuevo patrón de uso de GCD y también satisface viejo instanciación prevención patrón de Apple.

@implementation AAA
+ (id)alloc
{
    return  [self allocWithZone:nil];
}
+ (id)allocWithZone:(NSZone *)zone
{
    [self doesNotRecognizeSelector:_cmd];
    abort();
}
+ (instancetype)theController
{
    static AAA* c1  =   nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^
    {
        c1  =   [[super allocWithZone:nil] init];

        // For confirm...       
        NSLog(@"%@", NSStringFromClass([c1 class]));    //  Prints AAA
        NSLog(@"%@", @([c1 class] == self));            //  Prints 1

        Class   real_superclass_obj =   class_getSuperclass(self);
        NSLog(@"%@", @(real_superclass_obj == self));   //  Prints 0
    });

    return  c1;
}
@end

1voto

Walt Sellers Puntos 1706

Alternativamente, Objective-C proporciona el + método initialize (void) para NSObject y todas sus subclases. Siempre se llama antes de cualquier método de la clase.

Que establecer un breakpoint en una vez en iOS 6 y dispatch_once aparecieron en los marcos de pila.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X