Problema semantico: il getter sintetizzato della proprietà segue la convenzione di denominazione del cacao per restituire oggetti "posseduti"


283

Attualmente sto usando l'SDK di iOS 5 per provare a sviluppare la mia app. Sto cercando di rendere una proprietà NSString e quindi di sintetizzarla nel file .m (l'ho già fatto senza problemi). Ora, mi sono imbattuto in questo: "Problema semantico: il getter sintetizzato della proprietà segue la convenzione di denominazione del cacao per restituire oggetti" di proprietà ".

Questo è il mio codice: .h

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

.m

@synthesize newTitle;

Qualcuno ha idea di come potrei risolvere questo problema? Grazie!!


Ho avuto un errore molto simile "La proprietà segue le convenzioni di denominazione del cacao per la restituzione di oggetti" di proprietà ". La risposta di Bavarious sembra risolvere anche questo.
TMin

Risposte:


606

La mia ipotesi è che la versione del compilatore che stai usando segua anche le regole di gestione della memoria per le proprietà dichiarate - più specificamente, per gli accessori delle proprietà dichiarate:

Assumi la proprietà di un oggetto se lo crei utilizzando un metodo il cui nome inizia con "alloc", "new", "copy" o "mutableCopy".

Una proprietà denominata newTitle, quando sintetizzata, produce un metodo chiamato -newTitle, quindi avviso / errore. -newTitlesi suppone che sia un metodo getter per la newTitleproprietà, tuttavia le convenzioni di denominazione affermano che un metodo il cui nome inizia con newrestituisce un oggetto di proprietà del chiamante, che non è il caso dei metodi getter.

Puoi risolvere questo:

  1. Rinominare quella proprietà:

    @property (strong, nonatomic) NSString *theNewTitle;
  2. Mantenere il nome della proprietà e specificare un nome getter che non inizia con uno dei prefissi del nome del metodo speciale:

    @property (strong, nonatomic, getter=theNewTitle) NSString *newTitle;
  3. Mantenere sia il nome della proprietà che il nome del getter e dire al compilatore che, anche se il nome del getter inizia con new, appartiene alla nonefamiglia del newmetodo invece della famiglia del metodo:

    #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
    

    Si noti che anche se questa soluzione consente di mantenere newTitlesia il nome della proprietà sia il nome getter, avere un metodo chiamato -newTitleche non restituisce un oggetto di proprietà del chiamante può essere fonte di confusione per le altre persone che leggono il codice.


Per la cronaca, Apple ha pubblicato Transitioning to ARC Release Notes , in cui dichiarano:

Non è possibile assegnare a una proprietà un nome che inizia con newo copy.

Sono già stati informati che la loro affermazione non è del tutto accurata: il colpevole è il nome del metodo getter, non il nome della proprietà.


Modifica 17 gennaio 2015: ho appena notato un recente commit a Clang che suggerisce l'opzione 3 sopra (usando objc_method_family(none)), incluso un fix-it, per il caso generale in cui un nome di proprietà corrisponde a uno dei prefissi della famiglia del metodo speciale. Xcode probabilmente incorporerà questo cambiamento alla fine.


6
Ha funzionato come un uomo di fascino !! Grazie!!! Per riferimento futuro - ho usato "@property (strong, nonatomic, getter = theNewTitle) NSString * newTitle;"
Noam,

8
Risposta meravigliosa Avevo il prefisso "nuovo".

Anch'io ho questo problema e mi fa perdere molto tempo! Sei davvero un genio ~ Grazie!
H Lai,

NS_RETURNS_NOT_RETAINEDè anche quello di cui hai bisogno.
DawnSong

55

Nomi oggetto inaccettabili

  • pulsante Nuovo
  • copyLabel
  • allocTitle

Nomi oggetto accettabili

  • neueButton
  • mCopyLabel
  • _allocTitle

#arc # sintetizzato automaticamente # xcode-4.6.1

** MODIFICARE **

Apparentemente non puoi nemmeno usare mutableCopy .


1
Ho anche notato che "copia" non può essere utilizzato al momento.
Rishab,

30

Il nome del membro che inizia con new è ciò che attiva l'avviso. Cambia il nome in modificatoTitle e l'avvertimento sparirà. Non sono stato in grado di trovare documentazione che lo confermasse, ma attraverso i test sono stato in grado di determinare che le variabili membro che iniziano con "nuovo" aggravano il compilatore.


8

ARC non consente di utilizzare "Nuovo ...." nel nome della proprietà. ma puoi usare "newTitle" cambiando il nome getter.

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

6

Non sembra che ciò che Bavarious stava suggerendo fosse quello che volevi fare. Tutto quello che vuoi fare è dichiarare una variabile di istanza NewTitlee quindi sintetizzare la proprietà. Prima dovevamo dichiarare la variabile e la proprietà dell'istanza. Non piu.

Ora, credo che il modo giusto per farlo sia il seguente:

.h

@interface ViewController : UIViewController

@property (nonatomic, strong) NSString *newTitle;

.m

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

La variabile di istanza per la proprietà newTitleè sintetizzata. Non vuoi che la tua variabile di istanza sia la stessa della tua proprietà - troppo facile per commettere errori .

Vedi Esempio: dichiarazione delle proprietà e sintesi degli accessori


Dipende dalla versione del compilatore. Le versioni recenti di clang emettono un avviso in questo caso, motivo per cui ho menzionato la versione del compilatore nella mia risposta.

Non penso che tu abbia risolto il problema. Per Xcode 9, è un errore, non un avviso. NS_RETURNS_NOT_RETAINEDè quello che ti serve.
DawnSong

4

In CoreData se si utilizza l'attributo "nuovo ..." (compilare normalmente) si arresta in modo casuale con un'eccezione "accesso errato".

Non esiste un registro degli arresti anomali e la riga mostrata con il "Punto di interruzione di tutte le eccezioni" non ti aiuterà affatto.


3

La scrittura manuale di un setter con lo stesso nome della proprietà ha rimosso questo avviso.


In Xcode 7.3, questo non ha aiutato. Viene ancora visualizzato un errore nella riga di definizione della proprietà.
arlomedia,

1

Oltre al problema che dovresti / non puoi usare "nuovo" davanti ai tuoi nomi di proprietà, diciamo ancora una cosa: cerca di evitare "nuovo" davanti ai nomi in generale. "Nuovo" dipende dal tempo. Attualmente è nuovo per te, ma qualche tempo dopo potresti voler implementare qualcosa di nuovo. Quindi usare "nuovo" nei nomi è sempre negativo. Prova a pensare in questo modo: nel mondo della programmazione, "nuovo" crea sempre qualcosa: una nuova istanza di qualcosa.

Nel caso in cui si desideri assegnare un titolo diverso, il nome corrente verrà sostituito dal titolo della proprietà.

Un'altra cosa: prova prima a nominare funzioni e metodi con il verbo, come setSomething o getSomething. Ma nelle proprietà prova prima a nominare l'oggetto, come heightMinimum, heightMaximum, ecc. -> quando usi il tuo ispettore mentre stai programmando, cerchi sempre oggetti. Provalo. ;-)


1

NS_RETURNS_NOT_RETAINED viene utilizzato per risolvere il problema di denominazione.

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

Possiamo trovare la sua definizione come segue,

#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))

L'attributo 'ns_returns_not_retained' è il complemento di 'ns_returns_retained'. Laddove una funzione o un metodo sembrano obbedire alle convenzioni Cocoa e restituire un oggetto Cocoa mantenuto, questo attributo può essere usato per indicare che il riferimento oggetto restituito non deve essere considerato come riferimento "proprietario" restituito al chiamante. Il framework Foundation definisce una macro NS_RETURNS_NOT_RETAINED che è funzionalmente equivalente a quella mostrata di seguito.

Allega maggiori dettagli qui.


-2

prova questo:-

@property (nonatomic,retain) NSString *newTitle;

1
Comunque, stesso identico problema. Cordiali saluti, la riga di errore si trova sulla riga @synthesize.
Noam,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.