Domanda

Sto riflettendo su questa domanda da un po 'di tempo ...

Da un lato, Interface Builder offre un modo davvero semplice per progettare l'interfaccia e collegare gli elementi con oggetti in codice.

D'altra parte, nei progetti più grandi, Interface Builder diventa una seccatura da mantenere.

Eventuali suggerimenti sarebbero molto apprezzati.

È stato utile?

Soluzione

Una volta ero fortemente contrario all'utilizzo di Interface Builder nei miei progetti. Ciò era dovuto a una serie di fattori. Ho iniziato a lavorare con gli strumenti Xcode quando l'SDK per iPhone era tornato in beta (intorno al marzo 2008) e, poiché non provenivo da un background Mac Cocoa, non avevo familiarità con l'uso. Questo non è stato il fattore principale nel mio rifiuto iniziale di IB per lo sviluppo di iPhone, tuttavia: Interface Builder per lo sviluppo di iPhone durante la beta iniziale di iPhone SDK ha effettivamente fatto schifo ed è stato un dolore da usare.

Tuttavia, la storia è molto diversa dall'odierno SDK per iPhone. Mentre ci sono ancora alcuni fastidiosi bug IB, ho fatto quasi 180 & # 730; con il mio atteggiamento verso l'utilizzo di Interface Builder. Il più delle volte è una buona idea usare Interface Builder nei tuoi progetti, ho scoperto. Ora è un ottimo strumento e dovresti servirti.

Ora, non fraintendermi: sono ancora saldamente nel campo che crede che dovresti essere in grado di implementare qualsiasi cosa che fai in Interface Builder usando solo il codice e penso di essere in grado di farlo è inestimabile. Non usare Interface Builder come stampella, alla fine ti farai solo del male (e della tua produttività o qualità dei tuoi prodotti). Mentre le prelibatezze di trascinamento della selezione di IB sono ottime per il 90% di ciò che devi fare, quando hai qualcosa di personalizzato da implementare che può essere fatto solo nel codice, vorresti averlo seguito o essere grato per aver seguito questo consiglio. Ho avuto la fortuna di odiare IB abbastanza a lungo da insegnare a me stesso come fare tutto nel codice da solo, e poi applicare quella conoscenza a IB.

Modifica
Per ovviare alla mancanza di riusabilità (percepita o reale) con i NIB rispetto al codice ... non implementerai qualcosa che dovrebbe essere pesantemente riutilizzato in Interface Builder con ogni probabilità. Non puoi davvero effettuare un controllo o una visualizzazione personalizzati in IB, quindi è escluso e nella maggior parte dei casi stai implementando una sottoclasse del controller di visualizzazione creata per soddisfare uno scopo specifico. Ovviamente dovresti sempre cercare di rendere il tuo codice e le risorse associate il più riutilizzabili possibile. Ciò potrebbe includere considerazioni di progettazione per assicurarsi di non duplicare inutilmente le sottoclassi del controller di visualizzazione che sono molto simili.

Altri suggerimenti

L'uso di builders ti libera dal codice che altrimenti avresti bisogno di mantenere e meno hai bisogno di mantenere, meglio è

I layout creati da IB richiedono un po 'di manutenzione ma è uno strumento standard con la propria documentazione e il proprio supporto online (forum, elenchi, ecc.). Se qualcun altro dovesse mai saltare nel tuo codice, puoi praticamente garantire che abbiano esperienza con IB, ma non necessariamente il tuo particolare stile di costruzione del layout.

Dipende dalle tue preferenze.

Preferisco scriverlo in codice.

  1. Posso riutilizzare il codice.
  2. L'uso di XIB / NIB generalmente infrange la regola di una definizione (se si sta eseguendo una personalizzazione).
  3. La manutenzione XIB / NIB è spesso più noiosa e soggetta a errori (ODR). Non mi piace molto mantenere gli stili dei pulsanti (esempio) per ciascun pulsante.
  4. i riferimenti circolari sono più probabili.
  5. Le istanze di codice / oggetti / ib sono spesso meno riutilizzabili / modulari. Anche se sono il tipo da evitare un oggetto dell'interfaccia utente che può fare tutto.
  6. L'ordine di inizializzazione differito / ambiguo crea uno stato piuttosto spaventoso per i client, che non devono mai presumere che un oggetto sia pronto per l'uso o completamente inizializzato (a meno che non si preferisca mantenere tali controlli, il che è un buon modo per perdere tempo).
  7. Se le prestazioni sono importanti, indovina quale è più veloce?
  8. Gestione delle risorse vs linker ... seriamente, ho scritto sottoprogrammi e test per verificare l'esistenza dei pennini nel pacchetto.

IB è ottimo per la prototipazione e la visualizzazione di funzionalità e aspetti dell'oggetto (non sono un graphic designer), sebbene penso sia più semplice scriverlo nel codice una volta che il prototipo esiste se si dispone di intenzione di mantenerlo o riutilizzarlo.

La mia raccomandazione: scrivere librerie di codici altamente riutilizzabili e stabili e utilizzare IB principalmente per prototipazione e pezzi unici.


Risposte:

  

Sbrocket: sono curioso di sapere perché affermi che è più probabile che si verifichino riferimenti circolari a seguito dell'utilizzo di NIB.

Ciao Sbrocket: inizierò dicendo che ho usato Interface Builder dai tempi di Project Builder (il predecessore di Xcode).

Mancanza di proprietà strutturata, identità e inizializzazione affidabili. Non voglio che gli ivar siano connessioni IB perché rende difficile l'uso di molte classi oltre "l'attuale contesto", in altre parole, lega il codice alla risorsa (più spesso che idealmente). Poiché non è possibile definire l'ordine di inizializzazione o definire inizializzatori o argomenti di inizializzazione aggiuntivi in ??IB, è necessario quindi far conoscere gli oggetti l'uno dell'altro, creando dipendenze e riferimenti circolari.

  

Sbrocket: o perché l'inizializzazione pigra (supponendo che in realtà sia ciò a cui ti riferisci) è così spaventosa quando è relativamente facile (o in effetti automatica in molti casi) per garantire che l'oggetto sia inizializzato e connesso.

Ri: spaventoso Non stavo parlando di inizializzazione pigra. Stavo parlando di un ordine di inizializzazione differito e ambiguo.

L'inizializzazione del pennino è semi-ordinata. L'ordine / processo effettivo può variare e questo non può essere utilizzato in modo affidabile all'interno di programmi introspettivi riutilizzabili ... di nuovo, finiresti per scrivere troppo codice che è fragile, impossibile da riutilizzare, non si può mai essere certi di comportarsi in modo prevedibile e deve convalida sempre lo stato (ancora un'altra voce per la dipendenza circolare). Se non si tratta di un'implementazione unica, perché preoccuparsi delle complicazioni?

Questo approccio alla programmazione è caotico e le implementazioni devono (a loro volta) essere preparate per gestire qualsiasi cosa in qualsiasi momento. Una cosa è proteggersi dagli arresti anomali, ma scrivere un codice difensivo a livello di produzione in questo contesto ... assolutamente no.

È molto più facile scrivere un programma coerente la cui inizializzazione determina la validità nel contesto, che le implementazioni possono quindi sapere (se inizializzate) che l'oggetto è generalmente pronto per essere usato. La complessità dei casi speciali è ridotta al minimo. Molti di questi progetti cadono a pezzi man mano che aumenta la complessità del programma, mentre gli scrittori di biblioteche aggiungono strati su strati di "misure protettive" solo per far muovere gli ingranaggi: il threading è una voce eccellente per tali heisenbugs. Ambiguità non necessarie non sono gradite nel codice di livello di produzione riutilizzabile; gli esseri umani non dovrebbero dover fare riferimenti incrociati a tutti i casi speciali di un programma e le complessità relative al comportamento definito e ai casi speciali si diffondono o vengono ignorate (supponendo che siano adeguatamente tracciate e documentate, il che rappresenta uno sforzo più combinato rispetto alla scrittura corretta dall'inizio) ). Penso che possiamo essere tutti d'accordo sul fatto che interfacce e implementazioni onerose dovrebbero essere evitate.

  

Sbrocket: sarei anche interessato a vedere alcuni numeri concreti che mostrano che il caricamento del NIB è più lento - ovviamente, a prima vista sembrerebbe sensato, ma siamo sempre così cattivi predittori di colli di bottiglia delle prestazioni senza alcuni test difficili.

Non ho mai detto (esplicitamente) che era più lento :)

Ok, sul serio, l'archiviazione della NIB è stata (per me) un processo sorprendentemente lento, sebbene le nostre idee sui tempi lenti e non archivianti possano variare drasticamente.

Esempio: avevo un'app basata su documento e il caricamento del pennino era più volte più lento del caricamento del documento, quando le dimensioni del documento erano diverse volte le dimensioni del pennino. Spostare l'implementazione nel codice ha reso il processo molto più veloce. Una volta che era su codice e ho avuto il controllo dell'ordine di inizializzazione, ho rimosso più complessità multithreading (checkpoint, blocchi, voci delle condizioni di gara, ecc.), Che hanno reso il caricamento del documento ancora più veloce.

Ora che hai una risposta esplicita, ti ricorderò che hai tutti gli strumenti di cui hai bisogno per misurare le prestazioni.

Ricorda che l'analisi delle prestazioni e i miglioramenti sono appresi .

Il builder di interfacce è ottimo per un certo livello di complessità. Per cose più o meno complesse, preferirei farlo nel codice.

Se hai un'interfaccia che non verrà utilizzata in più di un modo, ha diversi ma non molti elementi e non ha bisogno di alcun layout complicato, allora IB è eccezionale.

A lungo termine, non uso quasi mai IB. Questa è la natura dei progetti su cui lavoro, come preferenza personale. Esistono sicuramente alcune interfacce per le quali andrei direttamente a IB, ma non ho bisogno di crearne una da un po '.

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