Problem semantyczny: Zsyntetyzowany getter właściwości jest zgodny z konwencją nazewnictwa kakao dla zwracanych „posiadanych” obiektów

283

Obecnie używam pakietu iOS 5 SDK, próbując opracować moją aplikację. Próbuję uczynić NSString właściwością, a następnie zsyntetyzować go w pliku .m (robiłem to wcześniej bez żadnych problemów). Natknąłem się na to: „Problem semantyczny: Zsyntetyzowany getter właściwości jest zgodny z konwencją nazewnictwa kakao dotyczącą zwracania„ posiadanych ”obiektów.”

To jest mój kod: .h

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

.m

@synthesize newTitle;

Czy ktoś ma jakiś pomysł, jak to naprawić? Dzięki!!

Noam
źródło
Miałem bardzo podobny błąd: „Właściwość jest zgodna z konwencjami nazewnictwa kakao dla zwracania„ posiadanych ”obiektów”. Odpowiedź Bavariousa również wydaje się rozwiązać ten problem.
TMin

Odpowiedzi:

606

Domyślam się, że wersja kompilatora, której używasz, jest zgodna z regułami zarządzania pamięcią dla zadeklarowanych właściwości - a ściślej - dla akcesorów zadeklarowanych właściwości:

Przejmujesz własność obiektu, jeśli tworzysz go przy użyciu metody, której nazwa zaczyna się od „przydziel”, „nowy”, „kopiuj” lub „mutableCopy”.

Właściwość o nazwie newTitlepo zsyntezowaniu daje metodę o nazwie -newTitle, stąd ostrzeżenie / błąd. -newTitlema być metodą gettera dla newTitlewłaściwości, jednak konwencje nazewnictwa stanowią, że metoda, której nazwa zaczyna się od, newzwraca obiekt będący własnością obiektu wywołującego, co nie ma miejsca w przypadku metod gettera.

Możesz rozwiązać ten problem przez:

  1. Zmiana nazwy tej właściwości:

    @property (strong, nonatomic) NSString *theNewTitle;
  2. Zachowanie nazwy właściwości i określenie nazwy pobierającej, która nie zaczyna się od jednego ze specjalnych prefiksów nazw metod:

    @property (strong, nonatomic, getter=theNewTitle) NSString *newTitle;
  3. Zachowując zarówno nazwę właściwości, jak i nazwę modułu pobierającego, i informując kompilator, że nawet jeśli nazwa modułu pobierającego zaczyna się od new, należy do nonerodziny metod, a nie do newrodziny metod:

    #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
    

    Zauważ, że chociaż to rozwiązanie pozwala zachować newTitlezarówno nazwę właściwości, jak i nazwę modułu pobierającego, posiadanie metody -newTitle, która nie zwraca obiektu należącego do osoby wywołującej, może być mylące dla innych osób czytających Twój kod.


Dla przypomnienia Apple opublikowało Informacje o przejściu na ARC , w których stwierdza:

Nie możesz nadać właściwości nazwy zaczynającej się od newlub copy.

Zostali już powiadomieni, że ich oświadczenie nie jest całkiem dokładne: winowajcą jest nazwa metody pobierającej, a nie nazwa właściwości.


Edytuj 17 stycznia 2015: Właśnie zauważyłem ostatnie zatwierdzenie dla Clanga, które sugeruje opcję 3 powyżej (użycie objc_method_family(none)), w tym poprawkę, w ogólnym przypadku, gdy nazwa właściwości pasuje do jednego ze specjalnych prefiksów rodziny metod. Xcode prawdopodobnie ostatecznie wprowadzi tę zmianę.

Cœur
źródło
6
Pracował jak czarujący człowiek !! Dzięki!!! Do wglądu w przyszłości - użyłem „@property (silny, nieatomowy, getter = theNewTitle) NSString * newTitle;”
Noam
8
Cudowna odpowiedź. Zmienne miałem przedrostkiem „nowy”.
Mam też ten problem i marnuje dużo czasu! Jesteś naprawdę geniuszem ~ Dziękuję!
H Lai,
NS_RETURNS_NOT_RETAINEDjest również tym, czego potrzebujesz.
DawnSong
55

Niedopuszczalne nazwy obiektów

  • newButton
  • copyLabel
  • assignTitle

Dopuszczalne nazwy obiektów

  • neueButton
  • mCopyLabel
  • _allocTitle

#arc # auto-syntezowany # xcode-4.6.1

** EDYTOWAĆ **

Najwyraźniej nie można również użyć mutableCopy .

Jacksonkr
źródło
1
Zauważyłem również, że „kopia” nie może być na razie używana.
Rishab
30

Nazwa członka rozpoczynającego się od nowego powoduje ostrzeżenie. Zmień nazwę na editedTitle, a ostrzeżenie zniknie. Nie mogłem znaleźć dokumentacji potwierdzającej to, ale dzięki testom udało mi się ustalić, że zmienne składowe zaczynające się od „nowego” obciążają kompilator.

Michael
źródło
8

ARC nie pozwala na użycie „Nowy ....” w nazwie właściwości. ale możesz użyć „newTitle”, zmieniając nazwę gettera.

@property (nonatomic, strong, getter=theNewTitle) NSString *newTitle;
Sooop
źródło
6

Nie wygląda na to, co sugerował Bavarious, co chciałeś zrobić. Wszystko, co chcesz zrobić, to zadeklarować zmienną instancji, NewTitlea następnie zsyntetyzować właściwość. Kiedyś musieliśmy deklarować zmienną instancji i właściwość. Już nie.

Teraz uważam, że właściwy sposób to zrobić:

.h

@interface ViewController : UIViewController

@property (nonatomic, strong) NSString *newTitle;

.m

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

Zmienna instancji dla właściwości newTitlejest syntezowana. Nie chcesz, aby zmienna instancji była taka sama jak twoja właściwość - zbyt łatwa do popełniania błędów .

Zobacz przykład: Deklarowanie właściwości i syntezowanie akcesoriów

aquraishi
źródło
To zależy od wersji kompilatora. Najnowsze wersje clang emitują ostrzeżenie w tym przypadku, dlatego wspomniałem o wersji kompilatora w mojej odpowiedzi.
Nie sądzę, że rozwiązałeś problem. W przypadku Xcode 9 jest to błąd, a nie ostrzeżenie. NS_RETURNS_NOT_RETAINEDjest to, czego potrzebujesz.
DawnSong
4

W CoreData, jeśli użyjesz „nowego ...” w atrybucie (skompiluj normalnie), nastąpi awaria losowa z wyjątkiem wyjątku „zły dostęp”.

Nie ma dziennika awarii, a linia pokazana z punktem przerwania „Wszystkie wyjątki” w niczym ci nie pomoże.

las
źródło
3

Ręczne pisanie settera o nazwie takiej samej jak właściwość usunęło to ostrzeżenie.

Serge Rykovski
źródło
W Xcode 7.3 to nie pomogło. Błąd nadal pojawia się w wierszu definicji właściwości.
arlomedia
1

Oprócz kwestii, że powinieneś / nie możesz używać „nowego” przed nazwami nieruchomości, powiedzmy jeszcze jedno: staraj się unikać „nowych” przed nazwami w ogóle. „Nowy” zależy od czasu. Obecnie jest to dla Ciebie nowe, ale jakiś czas później możesz chcieć zaimplementować coś nowego. Dlatego używanie nazwy „nowy” w nazwach jest zawsze złe. Spróbuj myśleć w ten sposób: w świecie programowania „nowy” zawsze tworzy coś: nową instancję czegoś.

W przypadku, gdy chcesz przypisać inny tytuł, bieżąca nazwa to twoja właściwość titleReplacement.

Jeszcze jedno: spróbuj nazwać funkcje i metody w czasowniku, na przykład setSomething lub getSomething. Ale we właściwościach spróbuj najpierw nazwać obiekt, np. WysokośćMinimum, wysokośćMaksymalna itp. -> kiedy używasz inspektora podczas pisania kodu, zawsze szukasz obiektów. Wypróbuj to. ;-)

Philipp Schaller
źródło
1

NS_RETURNS_NOT_RETAINED służy do rozwiązania problemu nazewnictwa.

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

Możemy znaleźć jego definicję w następujący sposób,

#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))

Atrybut „ns_returns_not_retained” stanowi uzupełnienie „ns_returns_retained”. W przypadku gdy funkcja lub metoda może wydawać się być zgodna z konwencjami kakao i zwrócić zachowany obiekt kakao, ten atrybut można wykorzystać do wskazania, że ​​zwrócone odwołanie do obiektu nie powinno być uważane za odwołanie „będące właścicielem” zwracane do obiektu wywołującego. Framework Foundation definiuje makro NS_RETURNS_NOT_RETAINED, które jest funkcjonalnie równoważne do pokazanego poniżej.

Dołącz więcej szczegółów tutaj.

DawnSong
źródło
-2

Spróbuj tego:-

@property (nonatomic,retain) NSString *newTitle;
Gypsa
źródło
1
Wciąż ten sam dokładny problem. Do Twojej wiadomości, linia błędu znajduje się na linii @synthesize.
Noam