Domanda

Ho una sottoclasse UITableViewController che è istanziato, a seconda di dove è usato, in un pennino o tramite codice. In entrambi i casi voglio fare la personalizzazione nel metodo di inizializzazione. Vuol dire che ho bisogno di implementare sia initWithNibName:bundle: e initWithCoder:, e sarebbe ogni metodo chiamare il suo rispettivo super-inizializzazione?

Anche se non ho bisogno di questo proprio ora, che cosa se anche io voglio essere in grado di creare un'istanza del controller della vista con initWithStyle:? Avrei quindi bisogno di 3 diversi metodi init che replicano lo stesso comportamento?

Sembra che questo viola l'intero designato convenzione inizializzatore, come ci sarebbe essenzialmente 3 inizializzatori separati che non finiscono per chiamare un metodo init comune. O c'è un modo per creare un inizializzatore designata comune supportando 3 diversi percorsi istanziare?

È stato utile?

Soluzione

La mia confusione è basata sulla convinzione che ogni classe deve avere un unico inizializzatore designato. Questo non è vero, e nel caso di UITableViewController ci sono 3 inizializzatori designati (per quanto posso dire):

  1. initWithStyle: dichiarato localmente
  2. initWithNibName:bundle: ereditato da UIViewController
  3. initWithCoder: di adottare il protocollo NSCoding

È necessario eseguire l'override 1 o più di questi nella sottoclasse a seconda di come la sottoclasse viene creata un'istanza. Nel mio caso ho dovuto implementare # 2 e # 3 dal momento che la classe può essere caricato da un pennino, o un'istanza mediante codice con riferimento ad un pennino. (Immagino che sia raro che userete sia initWithStyle: e initWithNibName:bundle: per una singola classe.)

Ho trovato di Apple Coding Linee guida per Cocoa utile.

Altri suggerimenti

Internamente,

  • -initWithStyle: di UITableViewController chiama -init del super-quindi impostare l'Ivar _tableViewStyle.
  • -init di UIViewController chiama semplicemente -initWithNibName:bundle: con argomenti di default.
  • UITableViewController non di override -initWithNibName:bundle:.

Di conseguenza, se si ignora -initWithNibName:bundle: poi -initWithStyle: adotterà il cambio troppo. Certo, andare sul sicuro (come non si dovrebbe fare affidamento su dettagli di implementazione), sostituire entrambe.

(E nessuna necessità di sovrascrivere -initWithCoder: a meno che non si UN / archiviare le istanze.)

Per chiarire, initWithStyle:, essendo initializer pubblicato solo di UITableViewController nei documenti, è la sua una esplicita inizializzatore designato.

initWithNibName:bundle: è ereditato da UIViewController ed è l'inizializzatore designato per quella classe. Come tale, secondo orientamenti cacao, UITableViewController deve ignorare questo metodo (per attuazione). Tuttavia, questo non lo rende un inizializzatore designato di UITableViewController.

initWithCoder: è, come fai notare, un inizializzatore implicita designato dal NSCoding.

Implementazione:

- (void) viewDidLoad

e fare la vostra inizializzazione del componente lì.

Ha il vantaggio di fare solo l'inizializzazione quando la vista è effettivamente richiesto.

o semplicemente fare un metodo di configurazione separata invocato da tutti inizializzatori.

Un oltre ai posti sopra che -initWithCoder riferimento:

Se è stato aggiunto aggiunto il controller della vista al suo genitore tramite Interface Builder (per esempio: se il controller della vista è collegato a un controller barra delle schede in Interface Builder), allora avete bisogno di ignorare -initWithCoder

.

(-. InitWithnibName verrà chiamato solo quando si crea il controller della vista a livello di codice)

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