Семантическая проблема: синтезированный метод получения свойства следует соглашению об именовании Какао для возврата «собственных» объектов - PullRequest
280 голосов
/ 13 июня 2011

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

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

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

.m

@synthesize newTitle;

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

Ответы [ 10 ]

601 голосов
/ 13 июня 2011

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

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

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

Вы можете решить эту проблему:

  1. Переименование этого имущества:

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

    @property (strong, nonatomic, getter=theNewTitle) NSString *newTitle;
    
  3. Сохраняя имя свойства и имя получателя, и сообщая компилятору, что, хотя имя получателя начинается с 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.

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


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

50 голосов
/ 23 апреля 2013

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

  • newButton
  • copyLabel
  • allocTitle

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

  • neueButton
  • mCopyLabel
  • _allocTitle

# arc # auto-синтезированный # xcode-4.6.1

** EDIT **

Очевидно, вы не можете использовать mutableCopy .

29 голосов
/ 10 октября 2011

Имя участника, начинающееся с нового, вызывает предупреждение. Измените имя на editedTitle, и предупреждение исчезнет. Мне не удалось найти документацию, подтверждающую это, но с помощью тестирования удалось определить, что переменные-члены, начинающиеся с «new», ухудшают компилятор.

7 голосов
/ 09 мая 2013

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

@property (nonatomic, strong, getter=theNewTitle) NSString *newTitle;
5 голосов
/ 09 августа 2011

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

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

.h

@interface ViewController : UIViewController

@property (nonatomic, strong) NSString *newTitle;

.m

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

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

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

3 голосов
/ 07 ноября 2013

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

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

2 голосов
/ 07 февраля 2012

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

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

NS_RETURNS_NOT_RETAINED используется для решения проблемы именования.

@property (nonatomic, copy) NSString *newTitle NS_RETURNS_NOT_RETAINED;

Мы можем найти его определение следующим образом,

#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))

Атрибут 'ns_returns_not_retained' является дополнением к 'ns_returns_retained'. Если может показаться, что функция или метод подчиняются соглашениям Какао и возвращают сохраненный объект Какао, этот атрибут может использоваться для указания того, что возвращаемая ссылка на объект не должна рассматриваться как «принадлежащая» ссылка, возвращаемая вызывающей стороне. Платформа Foundation определяет макрос NS_RETURNS_NOT_RETAINED, функционально эквивалентный показанному ниже.

Прикрепить подробнее здесь.

0 голосов
/ 04 августа 2014

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

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

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

0 голосов
/ 13 июня 2011

попробуйте это: -

@property (nonatomic,retain) NSString *newTitle;
...