Domanda

Ho sentito ora da diverse fonti (stackoverflow.com, cacao-dev, documentazione, blog, ecc.) che è "sbagliato" utilizzare accessori e impostazioni (foo, setFoo :) nei metodi init e dealloc.Capisco che esiste una remota possibilità di confondere altri oggetti che stanno osservando la proprietà se lo fai.(viene fornito un semplice esempio Qui)

Devo però dire che non sono d'accordo con questa pratica per il seguente motivo:

Il nuovo runtime Objective-C (quello su iPhone e il runtime a 64 bit in 10.5) ti consente di dichiarare le proprietà senza dichiarando una ivar corrispondente.Ad esempio, la seguente classe verrà compilata perfettamente su 10.5 o per iPhone (dispositivo, non simulatore):

@interface Foo : NSObject { }

  @property (retain) id someObject;

@end

@implementation Foo

  @synthesize someObject;

@end

Comprendendo che quanto sopra è una classe Objective-C perfettamente valida, diciamo che decido di scrivere un inizializzatore e, per scopi di gestione della memoria, un metodo dealloc (poiché GC non è disponibile su iPhone).Tutto ciò che ho letto sugli inizializzatori e sulla deallocazione mi avrebbe portato a scrivere i due metodi seguenti:

- (id) init {
  if (self = [super init]) {
    //initialize the value of someObject to nil
    [self setSomeObject:nil];
  }
  return self;
}

- (void) dealloc {
  //setting someObject to nil will release the previous value
  [self setSomeObject:nil];
  [super dealloc];
}

Tuttavia, secondo la documentazione e l'opinione popolare, questo è "sbagliato".Quindi le mie domande sono queste:

  1. Come dovrei inizializzare someObject senza utilizzare la funzione di accesso?Potresti dire che il compilatore (o il runtime o qualsiasi altra cosa) garantirà che someObject sia già impostato su nil, ma credo che sarebbe un comportamento improprio fare affidamento su quello.Avendo un discreto background in C, ho riscontrato un discreto numero di bug dovuti alla mancata inizializzazione delle variabili, e questo sembra leggermente diverso.
  2. Come posso rilasciare someObject se non dovrei utilizzare la funzione di accesso nel metodo dealloc?

Se la risposta a una di queste domande è "non puoi", allora come può essere sbagliato utilizzare gli accessori nei metodi init e dealloc?

È stato utile?

Soluzione

Capisco che l'attuale 10,5 comportamento in base al quale i ivars sintetizzati non sono direttamente accessibili è considerato da Apple per essere un bug; si dovrebbe essere in grado di accedere direttamente, ma non è possibile.

Quindi, si dovrebbe essere in grado di fare:

someObject = nil;

anziché

self.someObject = nil;

Nel frattempo, utilizzando la funzione di accesso diretto è l'unico modo per farlo senza fornire un Ivar esplicito.

Aggiorna : Questo bug è stato corretto; ora si può fare someObject = nil bene.

Altri suggerimenti

EDIT (13 febbraio 2013): Come notato nel mio commento qui sotto, e soprattutto dopo l'aggiunta di ARC, ho cambiato idea al riguardo.Prima di ARC, ho riscontrato molti bug che causavano arresti anomali a causa di assegnazioni ivar errate init.IMO, soprattutto lavorando con team junior, i rari problemi con l'utilizzo degli accessori in init sono stati controbilanciati dai bug comuni dell'accesso a ivar.Poiché ARC ha eliminato questo tipo di bug, i bug rari ma possibili che utilizzano la funzione di accesso in init possono causare sono più importanti, quindi sono passato a supportare l'uso diretto di ivars in init E dealloc, e solo in quei luoghi;accessori ovunque sia possibile (ovviamente non è possibile utilizzare accessori all'interno dell'accessore stesso....)


Risposta PRE-ARC

Sono fortemente in disaccordo con coloro che si oppongono agli accessori in -init.In quasi tutti i casi questo è un ottimo posto per usare gli accessori e salva molti bug che ho visto nei nuovi programmatori Cocoa che invariabilmente non riescono a conservare durante l'assegnazione -init.

-dealloc è una chiamata più difficile.Ho una naturale inclinazione a utilizzare gli accessori lì (in modo che vengano utilizzati ovunque), ma può causare mal di testa a causa di KVO (o anche di NSNotifications se pubblichi una notifica di modifica nel tuo setter).Detto questo, anche se non utilizzo accessori in -dealloc, lo ritengo molto discutibile e Apple è molto incoerente al riguardo (sappiamo che stanno chiamando setView: in UIViewController -dealloc ad esempio).

In ogni caso, direi che il sottoutilizzo degli accessori ha causato 100 volte più bug di un utilizzo eccessivo.Sbaglierei sempre nel usarli tranne quando c'è una forte ragione per non farlo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top