2014-12-18 9 views
6

Ho provato ad avviare e passare da Obj-C a Swift oggi e stavo leggendo la documentazione. Ho provato a creare un IBOutlet facile in Swift e mi ha costantemente dato quegli errori.Richiesti IBOutlets e IBactions! alla fine

View Controller has no initialiser

init richiesto (coder aDecoder: NSCoder) { FatalError ("init (coder :) non è stato attuato")}

IBOutletproperty has non-optional type 'UILabel'

e che costantemente si apre con questo codice:

@IBOutlet var outputLabel : UILabel

ma quando aggiungo un! marchio, è in esecuzione senza errori in questo modo

@IBOutlet var outputLabel : UILabel!

Stessa cosa accade per IBActions ...

+0

Suggerirei di leggere la seconda risposta: http://stackoverflow.com/questions/24006975/why-create-implicitly-unwrapped-optionals È abbastanza utile. –

+0

@ DánielNagy posso chiedere, ho controllato alcuni video tutorial online e non hanno mai messo il! ... Perché non loro e dobbiamo? Grazie –

+0

Le esercitazioni video potrebbero non essere aggiornate: in origine il decoratore 'IBOutlet' ha reso la proprietà opzionale, questo è stato modificato molto presto. – jrturton

risposta

7

Prima di tutto conoscere, ciò che è effettivamente ! e ?

  • Uso ?: se il valore può diventare nullo, in futuro, in modo che si prova per questo.
  • Utilizzare !: se in realtà non dovrebbe diventare nullo in futuro, ma inizialmente deve essere nullo.

@IBOutlet:

Quando si dichiara una presa a Swift, il compilatore converte automaticamente il tipo ad un debole implicitamente scartato opzionale e assegna un valore iniziale di nil.

In effetti, il compilatore sostituisce @IBOutlet var name: Tipo con @IBOutlet weak var name: Type! = nil.

Xcode lo cambierà e imporrà limitarsi a dichiarare variabile di tipo opzione @IBOutlet, quindi seguire entrambi i tipi di dichiarazione per @IBOutlet è valido fino alla data.

@IBOutlet var outputLabel : UILabel! 
@IBOutlet var priceLabel : UILabel? 

Tuttavia, se controlli trascinare uno sbocco per un'etichetta in beta 4 questo accade:

@IBOutlet var priceLabel : UILabel! = nil 
+0

Grazie !! Quindi lo metto appena. E questo copre l'aspetto del tutorial quindi ... Ok –

5

Questo è corretto. In Swift, una variabile di tipo X non può essere nulla, il che significa che deve essere inizializzata. Ciò significa che è necessario inizializzarsi in un metodo init o inizializzare inline.

In generale, vista controllori saranno dichiarare variabili di tipi che sono facoltativi - per esempio,

@IBOutlet var outputLabel : UILabel!

Questo significa che non è necessario per inizializzare il outputLabel, e per impostazione predefinita, il suo valore viene nil. Questo è il modello generale per le variabili IBOutlet, poiché le variabili sono impostate al di fuori del metodo init.

Se non si rendono opzionali le variabili, è necessario inizializzarle. Se non si inizializza in linea, è necessario fornire un metodo init, quindi l'errore che si ottiene.

+0

Come posso fornire un init in swift? –

+0

È necessario guardare il controller della vista e sovrascrivere uno dei metodi 'init'. Ad esempio, ce n'è uno qui: init richiesto (coder aDecoder: NSCoder) {super.init (coder: aDecoder)} – tng

+0

Per fornire un inizializzatore è però necessario perdere il punto. Le uscite non vengono popolate su init, vengono popolate quando la vista viene caricata e saranno nulle fino a quel momento. – jrturton

5

I dati del generatore di interfaccia vengono caricati dopo l'avvio del controller di visualizzazione, pertanto le prese non possono avere valore dopo l'inizializzazione. Con le proprietà opzionali implicitamente non confezionate (prese in questo caso) si promette che le proprietà potrebbero essere nul dopo l'avvio dell'oggetto, ma il loro valore verrà assegnato successivamente (dopo il caricamento di pennino o storyboard).

1

Come Stack permette domande di stile Q e A, lo metterò anche in parole più semplici. Basta mettere il ! al e di outlet ragazzi. Grazie mille per il vostro aiuto.

0

L'errore

'required' initialized 'init(coder:)' must be provided by subclass of 'UIViewController' 

improvvisamente iniziato quando ho aggiunto

var start : NSDate 

in una sottoclasse precedentemente funzionante di UIViewController, altrimenti tutti in IB. passaggio a

var start : NSDate? 

corretto. È un errore così sorprendente (huh? Init? Coder?) Per una semplice modifica che qualcuno che avvia un'app potrebbe fare molto prima che incontrino i programmatori o crea i propri metodi init, che forse aiuta a mostrare esplicitamente che il bisogno di inizializzazione non è limitato a IBOutlets. Le risposte sopra descrivono la causa principale.

0

Quando le viste o i controller di vista sono inizializzati da un file di builder di interfaccia, le loro prese non possono essere ancora connesse. Saranno connessi solo dopo l'inizializzazione, quindi devono essere facoltativi. Quando dopo l'inizializzazione viene chiamato qualsiasi altro codice della classe, è garantito che questi punti di connessione siano connessi. Questo è il motivo per cui gli IBOutlet vengono sempre dichiarati come optionals implicitamente non caricati.