Quali initializer (s) per ignorare per UITableViewController sottoclasse
-
09-09-2019 - |
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?
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):
-
initWithStyle:
dichiarato localmente -
initWithNibName:bundle:
ereditato daUIViewController
-
initWithCoder:
di adottare il protocolloNSCoding
È 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)