2012-06-02 3 views
2

Вы можете создавать синглтоны различными способами. Мне интересно, что между ними лучше.Singleton Creation preference

+(ServerConnection*)shared{ 
    static dispatch_once_t pred=0; 
    __strong static id _sharedObject = nil; 
    dispatch_once(&pred, ^{ 
     _sharedObject = [[self alloc] init]; // or some other init method 

    }); 
    return _sharedObject; 
} 

Я мог видеть, что это сводится к чему-то очень быстрому. Я бы подумал, что проверка предиката будет другим вызовом функции. Другой:

+(ServerConnection*)shared{ 
    static ServerConnection* connection=nil; 
    if (connection==nil) { 
     connection=[[ServerConnection alloc] init]; 
    } 
    return connection; 
} 

Существуют ли какие-либо существенные различия между этими двумя? Я знаю, что они, вероятно, достаточно похожи, чтобы не беспокоиться об этом. Но просто интересно.

ответ

2

Главное отличие состоит в том, что первый использует Grand Central Dispatch, чтобы гарантировать, что код, создающий синглтон, будет запускаться только один раз. Который заверяет вас в том, что это будет синглтон.

Также GCD применяет угрозу безопасности, поскольку в соответствии со спецификациями каждый вызов dispatch_once будет выполняться синхронно.

Я бы рекомендовал это

+ (ConnectionManagerSingleton*)sharedInstance { 

    static ConnectionManagerSingleton *_sharedInstance; 
    if(!_sharedInstance) { 
     static dispatch_once_t oncePredicate; 
     dispatch_once(&oncePredicate, ^{ 
      _sharedInstance = [[super allocWithZone:nil] init]; 
     }); 
    } 

    return _sharedInstance; 
} 

+ (id)allocWithZone:(NSZone *)zone {  

    return [self sharedInstance]; 
} 

- (id)copyWithZone:(NSZone *)zone { 
    return self;  
} 

Взято отсюда http://blog.mugunthkumar.com/coding/objective-c-singleton-template-for-xcode-4/

Edit:

Вот ответ на то, что вы просите http://cocoasamurai.blogspot.jp/2011/04/singletons-your-doing-them-wrong.html

Edit 2 :

Предыдущий код для ARC, если вы хотите поддержку не дуга добавить

#if (!__has_feature(objc_arc)) 

- (id)retain { 

    return self;  
} 

- (unsigned)retainCount { 
    return UINT_MAX; //denotes an object that cannot be released 
} 

- (void)release { 
    //do nothing 
} 

- (id)autorelease { 

    return self;  
} 
#endif 

(Точно так, как описано на первой ссылке)

Наконец действительно хорошее объяснение о одиночек:

http://csharpindepth.com/Articles/General/Singleton.aspx

+0

Точно, на что я надеялся. Благодаря! – utahwithak

+1

В ручном удержании, не беспокойтесь обо всем, что отвлекает ерунду. Это просто сделает более поздний рефакторинг более сложным, и это куча лишнего совершенно ненужного кода. – bbum