2010-11-02 2 views
5

Что такое эквивалент java, синхронизированный в объективе c? Я хочу быть в состоянии сделать мой одноточечно метод безопасен, поэтому, когда это сборище вызывается из 2 разных потоков, они пытаются использовать его 1 на 1.Каков эквивалент синхронизации в Objective-C?

+(MyObject*) getSharedObject 
{ 
    if(!singleton) 
    { 
      singleton = [[MyObject alloc] init]; 
    } 
    return singleton; 
} 
+0

дубликата http://stackoverflow.com/questions/1215330/how-does-synchronized-lock-unlock-in-objective-c –

+1

Не совсем дубликат, связанный с этим вопрос конечно. –

ответ

10

Obj-C имеет синхронизированный построить

-(MyObject*) getSharedObject 
{ 
@synchronized(something) 
{ 
    if(!singleton) 
    { 
      singleton = [[MyObject alloc] init]; 
    } 
    return singleton; 
} 
} 

возвращения из в синхронизированный блок делает «правильный» вещь

+0

Просто небольшое исправление, я думаю, что OP хочет использовать статический метод. – onmyway133

9

ответ Джошуа является правильным, но требует, чтобы у вас есть объект, на котором для синхронизации. Выполнение этого для синглета может привести к разным нечетным условиям гонки, если вы не будете осторожны. Стандартный шаблон для одноточечного является инициализировать его в +initialize, используя dispatch_once, который делает правильную вещь:

static MyObject *singleton = nil; 

+ (void)initialize { 
    static dispatch_once_t pred; 
    dispatch_once(&pred, ^{ singleton = [[MyObject alloc] init]; }); 
} 

- (MyObject&)getSharedObject 
{ 
    return singleton; 
} 
+2

Синхронизируйте по классу singleton, а затем нечетные условия гонки. – JeremyP

+1

Этот стиль рекомендуется Apple. – Eonil

-1

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

if (!singleton) 
    @synchronized(something) 
     if (!singleton) 
     instantiate; 

Таким образом, можно избежать ненужной блокировки после того, как объект был создан экземпляр.

+2

Есть много тонких возможных условий гонки, связанных с двойной проверенной блокировкой. Я бы избегал этого. – JeremyP

+0

Это было не мое головокружение. Кстати, – JeremyP

+0

Я ценю вашу отзыв Джереми, я признаю, что я не знал о таких проблемах. Однако я по-прежнему считаю, что стоит попытаться понять эти проблемы и получить это право, особенно если этот код будет иметь высокий трафик, будет слишком плохо, чтобы сознательно добавить возможную точку зрения. Очень признателен! – fhj

8

Для синхронизации создания Singleton вы должны использовать класс singleton как объект для синхронизации. Это моя обычная картина:

+(MyObject*) singleton 
{ 
    static MyObject* singleton = nil; 
    @synchronized([MyObject class]) 
    { 
     if(singleton == nil) 
     { 
      singleton = [[MyObject alloc] init]; 
     } 
    } 
    return singleton; 
} 

Очки отметить:

  • Я сделал это метод класса. Фактически вам это не нужно, это будет работать как метод экземпляра.

  • Обычно в методах класса при обращении к классу вы должны использовать self (или [self class] в методах экземпляра). Однако это было бы неправильно, потому что подклассы синхронизировали использование другого объекта с классом MyObject.

  • Я положил обратную связь за пределы блока @synchronize. Вполне нормально возвращаться изнутри блока, но если вы это сделаете, вы получите предупреждение ложного статического анализатора, говорящее, что метод может не вернуть значение.


Редактировать

выше картина давно устарели. Это лучше всего использовать dispatch_once рисунка на

+(MyObject*) singleton 
{ 
    static dispatch_once_t onceToken; 
    static MyObject* singleton = nil; 

    dispatch_once (&onceToken, ^{ 
     singleton = [[MyObject alloc] init]; 
    }); 
    return singleton; 
} 
+2

static MyObject * singleton = nil; Разве это не задает одиночный объект ниль и повторно создает его каждый раз при вызове метода? – aryaxt

+0

IIRC, в ObjC, статический в основном означает, что «существует только один из них», поэтому он инициализируется только один раз. – JimR

+3

Статический объект в Obj-C такой же, как и в C, что означает, что строка будет инициализирована только один раз –

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