2013-02-14 3 views
3

Итак, у меня есть синглтон, и я пытаюсь понять разницу между этими двумя реализациями: функционально я попытался запустить свой код с обоими из них, и они оба работаютРазница между этими двумя реализациями инициализаторов потоков в объекте C

Тем не менее, я заметил, что в первой реализации нет [self alloc], который вызывается вместо этого, для вызова [super alloc]. Я немного озадачен этим. Это, кажется, работает, но это кажется немного волшебно так Im интересно, если кто-то может прояснить

1-й способ:

+(id)getSingleton 
{ 

    static dispatch_once_t pred; 
    dispatch_once(&pred, ^{ 
    locMgrSingleton = [[super alloc] init]; 

     }); 

    return locMgrSingleton; 

} 

Другой способ

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

    } 

    return locMgrSingleton; 
} 
+0

Первый должен использовать 'self alloc'. – rmaddy

+0

Вы спрашиваете о различиях в механизмах синхронизации или разнице между '[self alloc]' и '[super alloc]'? Для второго это может помочь: [Создание singleton с allocWithZone:] (http://stackoverflow.com/q/11962913) (при условии, что вы переопределили 'alloc', в любом случае). –

ответ

4

Использование [self alloc] против [super alloc] не имеет никакого значения, если только класс также переопределяет +alloc. Тем не менее, это должно быть вызвано [self alloc]. Готов поспорить, что он звонит super, потому что это, вероятно, было адаптировано из реализации, которая переопределяет +alloc, чтобы вернуть синглтон.

В любом случае, разница между этими двумя узорами, кроме self против super, объясняется в моем ответе на this other question, но в общем, dispatch_once() это современный способ сделать это. Это быстрее, чем @synchronized, и носит больше смыслового смысла.

1

Как указано на фиг. http://cocoasamurai.blogspot.fi/2011/04/singletons-your-doing-them-wrong.html, вызов dispatch_once просто кажется несколько быстрее, чем @synchronized(self).

Что касается причин, почему [super alloc] вместо [self alloc], я не вижу причин, по которым он конкретно относится к версии dispatch_once, но не к другому. В статическом методе self просто ссылается на сам класс (и super на свой прямой суперкласс), и я бы рассматривал его как стенографию для написания фактического имени класса, не более того.

Хотя я использовал только [self alloc], так как в любом случае я бы назвал имя текущего класса, а не его суперкласс. Не знаю, имеет ли какое-либо особое значение конкретный вызов [super alloc].

1

В методе класса self указывает на сам класс. В обеих ваших реализациях [self alloc], [MySingleton alloc] и [super alloc] все семантически эквивалентны, если только вы по какой-то нечетной причине не переопределяете +alloc.

Одна из причин, вы можете захотеть использовать [super alloc] над другими, когда вы явно пометить +alloc недоступен в вашей декларации с директивой компилятора:

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

или

+(instancetype) alloc NS_UNAVAILABLE;

В противном случае, компилятор поднимет ошибку, когда вы попробуете +alloc экземпляр вашего одноэлементного класса, и обычно это то, что вы nt, за исключением случаев, когда вы используете +alloc общий экземпляр singleton в dispatch_once.

Смежные вопросы