it-swarm.xyz

ошибка: записываемое атомарное свойство не может соединить синтезированный установщик/получатель с заданным пользователем установщиком/получателем

Я недавно пытался скомпилировать старый проект XCode (который раньше просто компилировался), и теперь я вижу много ошибок этой формы:

error: writable atomic property 'someProperty' cannot pair a synthesized setter/getter with a user defined setter/getter

Шаблон кода, который вызывает эти ошибки, всегда выглядит так:

// Interface:

@property (retain) NSObject * someProperty;

// Implementation:

@synthesize someProperty; // to provide the getter
- (void)setSomeProperty:(NSObject *)newValue
{
    //..
}

Я понимаю, почему генерируется ошибка. Я говорю компилятору синтезировать мои методы доступа к свойствам (как getter, так и setter), а затем сразу же после этого переопределяю setter вручную. Этот код всегда пах немного.

Итак, как правильно это сделать? Если я использую @dynamic вместо @synthesize, мне также придется написать геттер. Это единственный способ?

124
e.James

У меня была та же проблема, и после небольшого исследования, вот мой вывод об этой проблеме:

Компилятор предупреждает вас о @property, который вы объявили атомарным (то есть, опуская ключевое слово nonatomic), но вы предоставляете неполную реализацию того, как синхронизировать доступ к этому свойству. 

Чтобы это предупреждение исчезло:

Если вы объявляете @property атомарным, выполните одно из следующих действий:

  • используйте @dynamic или;
  • используйте @synthesize и сохраните синтезированный сеттер и геттер или;
  • обеспечить ручную реализацию both установщика и получателя (без использования одной из вышеуказанных директив).

Если вы объявляете @property с (nonatomic), то вы можете смешать ручную и синтезированную реализации геттеров и сеттеров.

Обновление: заметка об автосинтезе свойств

Начиная с LLVM 4.0, CLang обеспечивает автоматический синтез для объявленных свойств, которые не являются @dynamic. По умолчанию, даже если вы пропустите @synthesize, компилятор предоставит вам методы getter и setter. Тем не менее, правило для атомарных свойств остается тем же: пусть компилятор предоставит both геттер и сеттер, OR реализует их both самостоятельно!

216
octy

Вы должны также реализовать геттер. Пример:

// Interface:

@property (retain) NSObject * someProperty;

// Implementation:

- (void)setSomeProperty:(NSObject *)newValue
{
    @synchronized (self)
    {
        // ...
    }
}

- (NSObject *)someProperty
{
    NSObject *ret = nil;

    @synchronized (self)
    {
        ret = [[someProperty retain] autorelease];
    }

    return ret;
}
13
arturgrigor

Этот вопрос, среди других популярных запросов, полученных при поиске «Пользовательского свойства Objective C», не обновляется информацией о «setter =» или «getter =».

Итак, чтобы предоставить больше информации по этому вопросу:

Вы можете предоставить вызов @property своим собственным методом, написав

    @property(setter = MySetterMethod:, getter = MyGetterMethod)

Обратите внимание на двоеточие для предоставленного метода установки.

Справка документация Apple

EDIT: Я не совсем уверен, как новые изменения в свойствах Objective-C (теперь они намного более интеллектуальные) меняют ответы на этот вопрос. Возможно, все это должно быть помечено как устаревшее.

12
Matias Forbord

Для тех, кто получает эту ошибку не по описанной причине, вы, вероятно, имеете ту же проблему, что и я:

У вас есть @property с тем же именем, что и у метода - ().

Что-то вроде этого:

@property UIView *mainView;

-(UIView *)mainView;
0
Albert Renshaw