2010-06-30 8 views
9

Ho letto un numero di snippet che menzionano che non si dovrebbe mai usare la notazione a punti nei metodi init o dealloc. Tuttavia, non riesco mai a capire perché. Un post ha fatto cenno che ha a che fare con KVO, ma non di più.Objective-C Dot Syntax e Init

@interface MyClass : NSObject { 
    SomeObject *object_; 
} 
@property (nonatomic, retain) SomeObject *object; 
@end 

Questa implementazione è negativa?

@implementation MyClass 

@synthesize object = object_; 

- (id)initWithObject:(SomeObject *)object { 
    if (self = [super init]) { 
     self.object = object; 
    } 

    return self; 
} 
@end 

Ma questo va bene?

@implementation MyClass 

@synthesize object = object_; 

- (id)initWithObject:(SomeObject *)object { 
    if (self = [super init]) { 
     object_ = [object retain]; 
    } 

    return self; 
} 
@end 

Quali sono le insidie ​​nell'utilizzo di dot-notation all'interno di init?

+0

Sembra nel 2 ° esempio che dovresti scrivere object_ = [object retain]; – Vladimir

+0

risolto, il problema con esempi scritti rapidamente. ;) – MarkPowell

risposta

25

In primo luogo, non è la notazione puntata in particolare, sono gli accessor che non si dovrebbero usare.

self.foo = bar; 

è identico a

[self setFoo: bar]; 

e sono entrambi disapprovato all'interno init/dealloc.

Il motivo principale è perché una sottoclasse potrebbe ignorare gli accessor e fare qualcosa di diverso. Gli accessor della sottoclasse possono assumere un oggetto completamente inizializzato, cioè che tutto il codice nel metodo init della sottoclasse è stato eseguito. In realtà, nessuno di questi ha quando il tuo metodo init è in esecuzione. Allo stesso modo, le funzioni di accesso della sottoclasse possono dipendere dal metodo dealloc della sottoclasse non eseguito. Questo è chiaramente falso quando il tuo metodo dealloc è in esecuzione.

+0

Chiunque abbia già votato questa risposta, spiega perché l'hanno fatto? – JeremyP

1

Le ragioni che ho sentito per lo più sorgono a causa di quando scrivi i tuoi setter/getter. Quando si usano le versioni @synthesized predefinite dei metodi, non causerà molti problemi. Quando scrivi il tuo setter, generalmente avrà un effetto secondario sulla tua classe. Questo effetto collaterale non è probabilmente ricercato nell'iniziale, o causerà problemi se fa riferimento ad altri ivar che non sono stati ancora creati. Lo stesso problema nel dealloc, se si dispone di un effetto collaterale, ha il potenziale per far saltare in aria.