341 votos

Crear singleton mediante GCD del dispatch_once en Objective C

Si se puede atacar iOS 4.0 o superior

El uso de MCD, es la mejor manera de crear singleton en Objective C (subprocesos)?

+ (instancetype)sharedInstance
{
    static dispatch_once_t once;
    static id sharedInstance;
    dispatch_once(&once, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

215voto

Dave DeLong Puntos 156978

Esto es perfectamente aceptable y seguro para subprocesos manera de crear una instancia de la clase. Puede no ser técnicamente una "singleton" (que sólo puede ser 1 de estos objetos), pero como sólo utilice la [Foo sharedFoo] método de acceso al objeto, este es bastante bueno.

36voto

Nietzsche Puntos 146

instancetype

instancetype es sólo una de las muchas extensiones de lenguaje para Objective-C, con más que se añaden en cada versión nueva.

Saber de ti, amor.

Y lo tomamos como un ejemplo de cómo prestar atención a los detalles de bajo nivel puede dar ideas en poderosas nuevas formas para transformar Objective-C.

http://nshipster.com/instancetype/


+ (instancetype)sharedInstance
{
    static dispatch_once_t once;
    static id sharedInstance;

    dispatch_once(&once, ^
    {
        sharedInstance = [self new];
    });

    return sharedInstance;
}

+ (Class*)sharedInstance
{
    static dispatch_once_t once;
    static Class *sharedInstance;

    dispatch_once(&once, ^
    {
        sharedInstance = [self new];
    });

    return sharedInstance;
}

33voto

Spetruk Puntos 41

MySingleton.h

@interface MySingleton : NSObject

+(instancetype) sharedInstance;

+(instancetype) alloc __attribute__((unavailable("alloc not available, call sharedInstance instead")));
-(instancetype) init __attribute__((unavailable("init not available, call sharedInstance instead")));
+(instancetype) new __attribute__((unavailable("new not available, call sharedInstance instead")));
-(instancetype) copy __attribute__((unavailable("copy not available, call sharedInstance instead")));

@end

MySingleton.m

@implementation MySingleton

+(instancetype) sharedInstance {
    static dispatch_once_t pred;
    static id shared = nil;
    dispatch_once(&pred, ^{
        shared = [[super alloc] initUniqueInstance];
    });
    return shared;
}

-(instancetype) initUniqueInstance {
    return [super init];
}

@end

6voto

CanO Puntos 163

Usted puede evitar que la clase se asigna con sobrescribir el método alloc.

@implementation MyClass

static BOOL useinside = NO;
static id _sharedObject = nil;


+(id) alloc {
    if (!useinside) {
        @throw [NSException exceptionWithName:@"Singleton Vialotaion" reason:@"You are violating the singleton class usage. Please call +sharedInstance method" userInfo:nil];
    }
    else {
        return [super alloc];
    }
}

+(id)sharedInstance
{
    static dispatch_once_t p = 0;
    dispatch_once(&p, ^{
        useinside = YES;
        _sharedObject = [[MyClass alloc] init];
        useinside = NO;
    });   
    // returns the same object each time
    return _sharedObject;
}

5voto

Christian Puntos 1630

Dave es correcto, eso está perfectamente bien. Es posible que desee comprobar fuera de Apple docs en la creación de un singleton para obtener consejos sobre la implementación de algunos de los otros métodos para asegurarse de que sólo uno puede ser creado si las clases de elegir NO usar la sharedFoo método.

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