Семантичний випуск: Синтезований геттер власності дотримується конвенції про іменування какао щодо повернення "власних" об'єктів


283

Наразі я використовую iK 5 SDK для розробки свого додатка. Я намагаюся зробити властивість NSString, а потім синтезувати його у файлі .m (я це робив раніше, без проблем). Тепер я зіткнувся з цим: "Семантичний випуск: синтезований геть властивості слідує конвенції про іменування какао щодо повернення" власних "об'єктів".

Це мій код: .h

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

.m

@synthesize newTitle;

Хтось має підказку, як я міг це виправити? Дякую!!


У мене була дуже схожа помилка: "Властивість слідує умовам називання какао щодо повернення" власних "об'єктів" Відповідь Баваріоса внизу, здається, вирішує і це.
TMin

Відповіді:


606

Я гадаю, що версія компілятора, яку ви використовуєте, також дотримується правил управління пам'яттю для оголошених властивостей - точніше, для доступних оголошених ресурсів:

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

Властивість, названа newTitleпри синтезі, дає метод, який називається -newTitle, отже, попередження / помилка. -newTitleповинен бути методом getter для newTitleвластивості, однак умовами іменування визначено, що метод, ім'я якого починається зnew повернення об'єкта, який належить абоненту, що не стосується методів getter.

Вирішити це можна за допомогою:

  1. Перейменування цієї властивості:

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

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


Для запису Apple опублікувала « Перехід до приміток випуску ARC» , в яких вони заявляють:

Ви не можете надати властивості ім'я, яке починається з newабо copy.

Вони вже отримали повідомлення, що їх твердження не зовсім точне: винуватцем є ім'я методу getter, а не ім'я властивості.


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


6
Працював як чарівна людина !! Дякую!!! Для подальшої довідки - я використав "@property (сильний, неатомічний, getter = theNewTitle) NSString * newTitle;"
Ноам

8
Чудова відповідь. У мене були змінні з префіксом "новий".

У мене теж є ця проблема, і вона витрачає багато часу! Ви справді геній ~ Дякую!
H Lai

NS_RETURNS_NOT_RETAINEDце те, що вам теж потрібно.
DawnSong

55

Неприйнятні імена об’єктів

  • newButton
  • copyLabel
  • allocTitle

Допустимі назви об’єктів

  • neueButton
  • mCopyLabel
  • _allocTitle

#arc # автоматично синтезується # xcode-4.6.1

** редагувати **

Мабуть, ви також не можете використовувати mutableCopy .


1
Я також зауважив, що "копію" зараз не можна використовувати.
Ришаб

30

Ім'я члена, що починається з нового, - це те, що викликає попередження. Змініть ім’я на editedTitle, і попередження пройде. Мені не вдалося знайти документацію, яка підтверджує це, але за допомогою тестування вдалося визначити, що змінні учасника, що починаються з «нового», посилюють компілятор.


8

ARC не дозволяє використовувати "New ...." у назві властивості. але ви можете використовувати "newTitle", змінивши назву Getter.

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

6

Це не схоже на те, що Баваріус припускав, що ви хотіли зробити. Все, що вам потрібно зробити, - це оголосити змінну екземпляра, NewTitleа потім синтезувати властивість. Раніше нам доводилося оголошувати змінну примірника та властивість. Не більше.

Тепер я вважаю, що правильний спосіб зробити це наступний:

.h

@interface ViewController : UIViewController

@property (nonatomic, strong) NSString *newTitle;

.m

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

newTitleСинтезована змінна інстанція для властивості . Ви не хочете, щоб ваша змінна інстанція була такою ж, як ваша власність - занадто просто помилитися .

Див. Приклад: Декларування властивостей та синтезування аксесуарів


Це залежить від версії компілятора. Останні версії clang видають попередження в цьому випадку, саме тому я згадував версію компілятора у своїй відповіді.

Я не думаю, що ти вирішив проблему. Для Xcode 9 це помилка, а не попередження. NS_RETURNS_NOT_RETAINEDце те, що вам потрібно.
Світанок

4

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

Журналу аварійних збоїв не існує, і рядок, показаний "Усі точки виключення", зовсім не допоможе вам.


3

Написання сетера вручну з ім'ям, таким же, як і властивість, видалило це попередження.


У Xcode 7.3 це не допомогло. У рядку визначення властивості все ще з’являється помилка.
арломедія

1

Окрім питання, що ви повинні / не можете використовувати "нове" перед вами імен властивостей, скажімо ще одне: Намагайтеся уникати "нового" перед іменами взагалі. "Нове" залежить від часу. Наразі він для вас новий, але через деякий час ви, можливо, захочете знову реалізувати щось нове. Тож використання "нового" в іменах завжди погано. Спробуйте подумати так: У світі програмування «нове» завжди щось створює: новий екземпляр чогось.

У вашому випадку, коли ви хочете призначити інший заголовок, то поточна назва вашого власності titleReplacement.

Ще одне: Спробуйте спершу назвати функції та методи за допомогою дієслова, як setSomething або getSomething. Але у властивостях спробуйте найменувати об’єкт спочатку, як висотаMinimum, heightMaximum тощо -> коли ви використовуєте інспектора під час кодування, ви завжди шукаєте об'єкти. Спробуй. ;-)


1

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_reserved' є доповненням до 'ns_returns_reserved'. Якщо функція чи метод можуть виявлятись підпорядкованими умовам Какао та повертати збережений об'єкт Какао, цей атрибут може бути використаний для вказівки, що повернута посилання на об'єкт не повинна розглядатися як "власницька" посилання, яка повертається абоненту. Рамка фонду визначає макрос NS_RETURNS_NOT_RETAINED, який функціонально еквівалентний наведеному нижче.

Додайте більше деталей тут.


-2

спробуйте це:-

@property (nonatomic,retain) NSString *newTitle;

1
Все-таки те саме питання. FYI, рядок помилки знаходиться на лінії @synthesize.
Ноам
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.