Le variabili di istanza con underscore in Objective-C 2.0 e la rinomina con @synthetize portano ad avvisi di ottimizzazione con lo strumento ‘Analizza’ di Xcode 4

Possibile duplicato:
Come funziona una sottolineatura di fronte a una variabile in un lavoro di c-class objective-c?

Sto usando la stessa convenzione per la variabile di esempio e la denominazione delle proprietà come mostrato da sebnow nella sua risposta seguente:

variabile di istanza / denominazione dell’argomento metodo nell’objective C

Copia il suo codice di esempio qui:

@interface Foo : NSObject { id _bar; } @property (nonatomic, retain) id bar; - (id) initWithBar:(id)aBar; @end @implementation Foo @synthesize bar = _bar; - (id) initWithBar:(id)aBar { self = [super init]; if(self != nil) { _bar = aBar; } return self; } @end 

Nell’implementazione di alcuni metodi della class Foo, io uso ad esempio:

 _bar = aBar 

invece di usare:

 bar = aBar 

Lo strumento “Analizza” introdotto da Xcode 4 mi dà questo avvertimento (sto usando la versione 4.0.2):

La variabile di istanza ‘bar’ nella class ‘Foo’ non viene mai usata dai metodi nella sua @implementation (sebbene possa essere usata dai metodi di categoria)

Forse dovrei usare:

 self.bar = aBar 

Ma per le proprietà di sola lettura, questo non può funzionare, e oltre a questo, non sono sicuro che l’utilizzo del setter nella class stessa sia una buona pratica o meno.

Non sono nuovo in Objective-C, ma sono ancora all’inizio dell’apprendimento. Forse sto facendo qualcosa di sbagliato, e ho una ctriggers pratica di codifica da qualche parte.

Grazie in anticipo se puoi aiutarmi;)

“Non è mai usato” dovrebbe essere preso alla lettera: si definisce solo il suo valore in compiti, non si usa mai.

Questo è lo stesso tipo di avvertimento che si ottiene per le variabili locali: se si definiscono solo i propri valori e non si usano mai, a cosa servono?

L’analizzatore statico ti avvisa, perché in genere le variabili a cui non si accede mai sono solo resti di codice vecchio che è stato modificato e che è ansible rimuoverli. Ma nel tuo caso potrebbe andare perfettamente bene.

La linea @synthesize influenza il modo in cui il setter e il getter per la ‘barra’ della proprietà operano. La linea:

 @synthesize bar = _bar; 

Effettivamente dice “inserisci il getter standard (e setter, se rilevante) per bar, come per il modo in cui l’ho dichiarato come @property , ma usa la variabile di istanza _bar per l’archiviazione”.

Quando usi self.bar come un lvalue stai effettivamente facendo una chiamata di metodo a [self setBar:] e quando lo usi come valore di un rvalue stai effettivamente facendo una chiamata a [self bar] selfbar [self bar] . Sembra un normale accesso al membro della struct in stile C, ma internamente è una chiamata di metodo.

Quindi, @synthesize crea un getter e un setter adatti da utilizzare per self.bar , ma non cambia il nome della variabile di istanza. Dovresti quindi avere ragione a usare _bar quando _bar alla cosa direttamente dall’interno della class stessa (anche se alcune persone lo disapprovano da un punto di vista dello stile) e self.bar altrimenti, senza ricevere alcun avvertimento da parte dell’analizzatore.

Affinché tu finisca con una variabile di istanza chiamata bar , supponendo che tu non ne abbia dichiarata una nell’interfaccia, l’errore più probabile è un errore nel modo in cui hai eseguito @synthesize . Nel runtime moderno puoi fornire una @property/@synthesize coppia per una variabile che non hai effettivamente dichiarato nella tua interfaccia e la variabile sarà magicamente aggiunta alla tua interfaccia. Quindi puoi farlo per sbaglio se commetti uno sfortunato errore di battitura.

Se ansible, potresti pubblicare il tuo codice attuale?

Si prega di vedere il mio commento.

Prova ad aggiungere un metodo -dealloc per rilasciare l’object. Questo accederà all’Ivar e renderà felice l’analizzatore statico.

 -(void)dealloc { [bar release]; bar = nil; [super dealloc] } 

Ora che posso rispondere alla mia domanda 8 ore dopo, lo faccio per chiunque abbia commesso lo stesso errore di me durante alcuni test o qualcosa del genere. Tuttavia, le risposte di Sergio e Tommy sono molto istruttive.

Dopo aver letto le risposte, ho visto che ho fatto un errore stupido. Durante un test di codifica della mia class, ho rimosso il carattere di sottolineatura prima della dichiarazione delle variabili di istanza. Quindi il mio codice reale era davvero simile a questo:

 @interface Foo : NSObject { id bar; } @property (nonatomic, retain) id bar; - (id) initWithBar:(id)aBar; @end @implementation Foo @synthesize bar = _bar; - (id) initWithBar:(id)aBar { self = [super init]; if(self != nil) { _bar = aBar; } return self; } @end 

Quindi gli avvertimenti di Analisi erano corretti. Scusa per il falso allarme! Ma grazie per le risposte molto veloci.

usa questo ->

 @interface Foo : NSObject { id _bar; } @property (nonatomic, retain) id _bar; - (id) initWithBar:(id)aBar; @end @implementation Foo @synthesize bar = _bar; - (id) initWithBar:(id)aBar { self = [super init]; if(self != nil) { bar = aBar; } return self; } @end