2010-07-26 6 views
19

Quanto segue non si lamenta in fase di compilazione né runtime in merito a name ivar. Quindi, perché è così comune vedere un ivar e@property/@synthesize.Qual è lo scopo di un ivar quando esiste una proprietà?

@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; 
} 

stampe questo codice

Hello, World! 

Infatti, se accedo p->name, ottengo un avvertimento:

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

che indica che un Ivar è stato creato per me, se uno doesn' Esistono

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

Oppure chiesto in modo diverso, dovrei sempre solo creare un ivar per una proprietà quando è necessario ignorare gli accessor?

risposta

19

Ivars sintetizzati (la possibilità di non dichiarare manualmente ivars) sono una funzionalità 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.

+0

Penso che, come ha detto Cris, ci siano alcuni problemi con la mancata dichiarazione di ivars. Il debug è quello in cui mi imbatto abbastanza spesso. – Ian1971

8

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 attivare notifiche KVO. Con un ivar con cui parlare, puoi semplicemente inviare release e farlo. 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 sia grave questo 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.

ragioni
+1

Puoi ancora accedere a ivar direttamente con ivars sintetizzati (c'era un bug in cui non si poteva, ma sono abbastanza sicuro che sia corretto ora), quindi questo non è un problema. – shosti

+0

@eman: IIRC stanno pianificando una correzione, ma non è attiva a meno che non si stiano utilizzando build Xcode prerelease. – Chuck

+6

L'accesso diretto di ivars sintetizzati funziona al punto 3.2.4. –

7

Due non-così-bene-ma-necessarie per assicurarsi che le proprietà sono supportati da Ivars:

  1. Per qualche motivo il debugger XCode non mostra le proprietà che non hanno ivars corrispondenti esplicitamente dichiarato.
  2. Mi sembra che in alcune circostanze che utilizzano @property senza un Ivar può nascondere altri Ivars, con conseguente errori di compilazione (vedi Why does a subclass @property with no corresponding ivar hide superclass ivars?)

A meno che non ho le estremità sbagliata di un paio di bastoni qui , Penso che l'uso di @property senza ivars espliciti possa portare a fastidi non giustificati dalla praticità.

Problemi correlati