Семантическая проблема: синтезированный синтез 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;