Семантическая проблема: синтезированный синтез getter следует за Cocoa соглашением об именах для возврата "принадлежащих" объектов

В настоящее время я использую iOS 5 SDK, пытаясь разработать мое приложение. Я пытаюсь создать свойство NSString и затем синтезировать его в файле .m(я делал это раньше, без проблем). Теперь я наткнулся на это: "Semantic Issue: свойство, синтезированное getter, следует за Cocoa соглашением об именах для возврата" принадлежащих "объектов.

Это мой код: .h

@interface ViewController : UIViewController {
     NSString *newTitle;
}
@property (strong, nonatomic) NSString *newTitle;

.m

@synthesize newTitle;

Кто-нибудь знает, как я могу это исправить? Спасибо!!

Ответ 1

Мое предположение заключается в том, что используемая вами версия компилятора youre использует правила управления памятью для объявленных свойств - более конкретно, для объявленных свойств:

Вы получаете право собственности на объект, если его создаете с помощью метода, имя которого начинается с "alloc", "new", "copy" или "mutableCopy".

Свойство с именем newTitle при синтезе дает метод, называемый -newTitle, следовательно, предупреждение/ошибка. -newTitle должен быть методом getter для свойства newTitle, однако соглашения об именах указывают, что метод, имя которого начинается с new, возвращает объект, принадлежащий вызывающему, что не относится к методам getter.

Вы можете решить это:

  • Переименование этого свойства:

    @property (strong, nonatomic) NSString *theNewTitle;
    
  • Сохранение имени свойства и указание имени геттера, которое не начинается с одного из префиксов имени специального метода:

    @property (strong, nonatomic, getter=theNewTitle) NSString *newTitle;
    
  • Сохраняя как имя свойства, так и имя получателя, и сообщая компилятору, что, хотя имя получателя начинается с new, оно относится к семейству методов none, а не к методу new семейство:

    #ifndef __has_attribute
    #define __has_attribute(x) 0  // Compatibility with non-clang compilers
    #endif
    
    #if __has_attribute(objc_method_family)
    #define BV_OBJC_METHOD_FAMILY_NONE __attribute__((objc_method_family(none)))
    #else
    #define BV_OBJC_METHOD_FAMILY_NONE
    #endif
    
    @interface ViewController : UIViewController
    @property (strong, nonatomic) NSString *newTitle;
    - (NSString *)newTitle BV_OBJC_METHOD_FAMILY_NONE;
    @end
    

    Обратите внимание, что даже если это решение позволяет сохранить newTitle как имя свойства, так и имя получателя, имея метод с именем -newTitle, который не возвращает объект, принадлежащий вызывающему, может смущать других людей, читающих ваши код.


Для записи Apple опубликовала Переход к примечаниям о выпуске ARC, в которых говорится:

Вы не можете указать свойство, имя которого начинается с new или copy.

Они уже были уведомлены о том, что их утверждение не совсем точное: виновником является имя метода getter, а не имя свойства.


Редактировать 17 янв 2015: Я только что заметил недавнюю фиксацию Clang, которая предлагает вариант 3 выше (используя objc_method_family(none)), в том числе fix-it, для общего случая, когда имя свойства соответствует одному из префиксов семейства специальных методов. Вероятно, Xcode включит это изменение.

Ответ 2

Неприемлемые имена объектов

  • newButton
  • copyLabel
  • allocTitle

Допустимые имена объектов

  • neueButton
  • mCopyLabel
  • _allocTitle

#arС# автоматически синтезированный # xcode-4.6.1

** РЕДАКТИРОВАТЬ **

По-видимому, вы не можете использовать mutableCopy.

Ответ 3

Имя участника, начинающегося с нового, вызывает предупреждение. Измените имя на editTitle, и предупреждение исчезнет. Мне не удалось найти документацию, подтверждающую это, но через тестирование удалось определить, что переменные-члены, начинающиеся с "нового", усугубляют компилятор.

Ответ 4

ARC не позволяет использовать "New..." в имени свойства. но вы можете использовать "newTitle", изменив имя получателя.

@property (nonatomic, strong, getter=theNewTitle) NSString *newTitle;

Ответ 5

Это не похоже на то, что предлагал Бавариус, это то, что вы хотели сделать. Все, что вы хотите сделать, это объявить переменную экземпляра NewTitle, а затем синтезировать свойство. Нам приходилось объявлять переменную экземпляра и свойство. Больше.

Теперь я считаю, что правильный способ сделать это:

.h

@interface ViewController : UIViewController

@property (nonatomic, strong) NSString *newTitle;

.m

@synthesize newTitle = _newTitle; // Use instance variable _newTitle for storage

Синтезируется переменная экземпляра для свойства NewTitle. Вы не хотите, чтобы ваша переменная экземпляра была такой же, как ваша собственность, - слишком легко сделать ошибки.

См. Пример: Объявление свойств и синтезация аксессуаров

Ответ 6

В CoreData, если вы используете "new..." в атрибуте (обычно компилируетесь), он случайно разбивается с исключением "плохого доступа".

Нет журнала сбоев, и строка, показанная с помощью "Все точки останова исключений", не поможет вам.

Ответ 7

Написание сеттера вручную с таким же именем, как и свойство, удалило это предупреждение.

Ответ 8

Кроме того, что вы должны/не можете использовать "новые" перед вашими именами свойств, скажем еще одно: старайтесь избегать "новых" перед именами вообще. "Новое" зависит от времени. В настоящее время это ново для вас, но через некоторое время вы, возможно, захотите снова реализовать что-то новое. Поэтому использование "новых" в именах всегда плохое. Попробуйте подумать так: в мире программирования "новое" всегда создает что-то: новый экземпляр чего-то.

В вашем случае, если вы хотите назначить другой заголовок, то текущее имя вашего свойства titleReplacement.

Еще одна вещь: попробуйте сначала назвать функции и методы с глаголом, например setSomething или getSomething. Но в свойствах сначала попробуйте назвать объект, например heightMinimum, heightMaximum и т.д. → , когда вы используете своего инспектора при кодировании, вы всегда ищете объекты. Попробуйте.; -)

Ответ 9

попробуйте следующее: -

@property (nonatomic,retain) NSString *newTitle;