2015-04-20 26 views
5

Ho una domanda molto generale sull'inizializzazione in Swift. Diversamente dall'Obiettivo C è ora possibile chiamare init() direttamente alla dichiarazione al di fuori delle mie funzioni: ad es.Dove inizializzare in Swift?

class ViewController: UIViewController { 
    let myView: UIView = UIView() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     myView.frame = getFrame() 
     myView.backgroundColor = UIColor.redColor() 
     self.view.addSubview(myView) 

    } 

    func getFrame() -> CGRect { 
     return CGRectMake(0, 0, 100, 100) 
    } 
} 

Nell'obiettivo C avrei eseguito l'inizializzazione nella mia funzione.

Ma cosa succede se voglio chiamare un inizializzatore con parametri che non sono ancora impostati? ad es. Voglio init con un telaio che viene calcolato in un func()

class ViewController: UIViewController { 

    //THIS IS NOT WOKRING 
    let myView: UIView = UIView(frame: getFrame()) 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     myView.backgroundColor = UIColor.redColor() 
     self.view.addSubview(myView) 

    } 

    func getFrame() -> CGRect { 
     return CGRectMake(0, 0, 100, 100) 
    } 
} 

Non voglio fare il mio inizializzazioni in due luoghi diversi nel codice. C'è qualche schema generale per le inizializzazioni?

risposta

4

Così le opzioni per l'inizializzazione in rapido sono numerose. Con il tuo esempio corrente non puoi utilizzare il metodo getFrame() perché non hai ancora un riferimento a self dato che lo ViewController non è stato inizializzato. Invece è possibile utilizzare:

let myView: UIView = UIView(frame: CGRectMake(0, 0, 100, 100)) 

Poiché ciò non richiede il riferimento a sé. In alternativa si potrebbe lazy esemplificazione, che andranno eseguito dopo self è disponibile (questo può essere utilizzato solo con var non let:

lazy var myView: UIView = { 
    return UIView(frame:self.getFrame()) 
}() 

Per rispondere alla tua domanda, quando si utilizza classe UIKit dove spesso non si ha il controllo sulla loro esemplificazione si può continuare a farlo lo stesso era come lo siete stati in Objective C e utilizzare implicitly unwrapped optional (per evitare di dover utilizzare un ! o ? ogni volta che si crea un'istanza di una variabile, ad esempio:

var myView: UIView! 

override func viewDidLoad(){ 
    super.viewDidLoad(); 

    myView = UIView(frame:getFrame()) 
} 

Thi s tuttavia non funziona con le costanti let, in quanto devono essere assegnate immediatamente o nel costruttore dell'oggetto. Spero che questo ti aiuti.

+0

Grazie per l'ottima risposta! Come lo faresti? – Michael

+0

Non esiste una regola semplice e veloce in quanto dipende dal tipo di classe. Dicendo che normalmente dichiaro tutte le costanti in linea (ad esempio 'let'), uso' lazy var' per i valori con valori predefiniti e quindi inizializza tutte le variabili all'inizio del ciclo di vita della classe il più possibile. Quindi, nelle classi modello (ad es. 'Utente' o' Persona') nell'iniz e nel 'viewDidLoad' di un' UIViewController'. – Bulwinkel

Problemi correlati