ошибка: записываемое атомарное свойство не может соединить синтезированный установщик / получатель с заданным пользователем установщиком / получателем - PullRequest
127 голосов
/ 12 июля 2010

Я недавно пытался скомпилировать старый проект 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, мне также придется написать геттер.Это единственный способ?

Ответы [ 4 ]

217 голосов
/ 20 июля 2010

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

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

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

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

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

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

Обновление: примечание об автосинтезе свойств

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

13 голосов
/ 12 марта 2012

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

// 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;
}
12 голосов
/ 20 декабря 2011

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

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

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

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

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

Ссылка Документация Apple

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

0 голосов
/ 03 августа 2018

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

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

Примерно так:

@property UIView *mainView;

-(UIView *)mainView;
...