Qual è lo scopo di un ivar quando esiste una proprietà?

Quanto segue non si lamenta in fase di compilazione né di runtime su nessun name ivar. Quindi, perché è così comune vedere un ivar e @property/@synthesize .

 @interface PropTest : NSObject { } @property (retain) NSString *name; @end @implementation PropTest @synthesize name; @end int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; PropTest *p = [[PropTest new] autorelease]; p.name = @"Hello, World!"; NSLog(@"%@",p.name); [pool drain]; return 0; } 

Questo codice stampa

 Hello, World! 

Infatti, se p->name , ricevo un avviso:

 warning: instance variable 'name' is @private; this will be a hard error in the future 

che indica che per me è stato creato un ivar se non ne esiste uno.

Se è vero, che senso ha creare manualmente l’ivar (ignorando l’ovvio, che a volte ci sono validi motivi per non usare l’accessore di g / setter)?

O chiesto in modo diverso, dovrei mai solo creare un ivar per una proprietà quando ho bisogno di bypassare gli accessor?

I ivars sintetizzati (la capacità di non dichiarare manualmente ivars) sono una caratteristica del nuovo runtime Objective-C, che non è ancora in uso su tutti i sistemi. Per i Mac a 32 bit (e, fino a poco tempo fa, il simulatore di iPhone), devi dichiarare manualmente ivars. Se si stanno indirizzando solo i sistemi con il nuovo runtime, non c’è motivo di dichiarare manualmente ivars.

La risposta di eman è corretta nel complesso, ma c’è una ragione per dichiarare ancora ivars anche nel nuovo runtime: Apple scoraggia gli accessorizzatori sintetizzati nei metodi init e dealloc. In sostanza, getter e setter possono avere effetti collaterali diversi dall’impostare una variabile. In particolare, potrebbero triggersre notifiche KVO. Con un ivar con cui parlare, puoi semplicemente inviare il release e averne a che fare. Ma se tutto quello che hai è una proprietà, la tua unica scelta è impostarla e sperare di evitare eventuali interazioni sfortunate.

Non sono sicuro di quanto grande sia il problema nella pratica, ad essere onesti. L’ho evitato in modo superstizioso, anche se dubito segretamente che causerebbe un problema nella maggior parte dei casi. Ma Apple ha fatto un punto di questo nei documenti, quindi presumo che ci sia qualche motivo per essere preoccupati.

Due motivi non-così-buoni-ma-necessari per assicurarsi che le proprietà siano supportate da ivars:

  1. Per qualche ragione il debugger di XCode non mostra le proprietà che non hanno ivar corrispondenti esplicitamente dichiarate.
  2. Mi sembra che in alcune circostanze l’uso di @property senza un ivar possa hide altri ivar, con conseguenti errori di compilazione (vedi Perché una sottoclass di @property con nessun ivar corrispondente ha i superclass ivars? )

A meno che non abbia ottenuto le estremità sbagliate di un paio di stick qui, penso che l’uso di @property senza ivars espliciti possa portare a fastidi non giustificati dalla comodità.