2016-04-29 18 views
5

Come posso evitare di ripetere codice tra i miei inizializzatori? Voglio che dataFormatter rimanga una costante.Swift evitare di ripetere il codice nell'inizializzatore

let dateFormatter: NSDateFormatter 

init() { 
    dateFormatter = NSDateFormatter() 
    dateFormatter.dateStyle = .MediumStyle 
    dateFormatter.timeStyle = .MediumStyle 
    super.init(nibName: nil, bundle: nil) 
} 

required init?(coder aDecoder: NSCoder) { 
    dateFormatter = NSDateFormatter() 
    dateFormatter.dateStyle = .MediumStyle 
    dateFormatter.timeStyle = .MediumStyle 
    super.init(coder: aDecoder) 
} 

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { 
    dateFormatter = NSDateFormatter() 
    dateFormatter.dateStyle = .MediumStyle 
    dateFormatter.timeStyle = .MediumStyle 
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) 
} 

risposta

9

Se questa è la davvero il codice vero e sostituire tutto il codice con

lazy var dateFormatter : NSDateFormatter = { 
    let formatter = NSDateFormatter() 
    formatter.dateStyle = .MediumStyle 
    formatter.timeStyle = .MediumStyle 
    return formatter 
}() 

La variabile è pigramente inizializzata una volta quando viene letta la prima volta

Edit: E 'inoltre possibile dichiarare la variabile come costante senza l'attributo lazy.

let dateFormatter : NSDateFormatter = { ... 

La differenza è che il formattatore viene creata immediatamente (non pigramente) durante l'inizializzazione dell'istanza.

Edit:

In Swift 3 NSDateFormatter è stato rinominato in DateFormatter
e .MediumStyle-.mediumStyle

+1

per essere pigro, è necessario aggiungere il prefisso pigro qui giusto? e cambia let a var. altrimenti la logica di formattazione della data non sarà lassista, ma verrà invece chiamata ogni volta che vi si accede. –

+1

No, è possibile utilizzare entrambi i moduli, l'ho appena testato in un parco giochi. – vadian

+0

'NOTA È sempre necessario dichiarare una proprietà lazy come variabile (con la parola chiave var), poiché il suo valore iniziale potrebbe non essere recuperato fino al completamento dell'inizializzazione dell'istanza. Le proprietà costanti devono sempre avere un valore prima che l'inizializzazione sia completata e, pertanto, non possono essere dichiarate pigre. [Source] (https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html) – Laffen

0

Questo è l'unico modo in cui mi veniva in mente:

class Sample: UIViewController { 
    let dateFormatter: NSDateFormatter = NSDateFormatter() 

    init() { 
     super.init(nibName: nil, bundle: nil) 
     setupDateFormatter() 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     setupDateFormatter() 
    } 

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { 
     super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) 
     setupDateFormatter() 
    } 

    private func setupDateFormatter() { 
     dateFormatter.dateStyle = .MediumStyle 
     dateFormatter.timeStyle = .MediumStyle 
    } 
} 
+0

Apprezzo la tua risposta. Ho modificato il mio post se sei interessato. –

3

In questo caso si potrebbe set the default property value of the date formatter using a closure.

Allora la vostra dichiarazione di proprietà diventa:

let dateFormatter: NSDateFormatter = { 
    let dateFormatter = NSDateFormatter() 
    dateFormatter.dateStyle = .MediumStyle 
    dateFormatter.timeStyle = .MediumStyle 
    return dateFormatter 
}() 

ed è possibile rimuovere i bit formattatore data dai vostri inizializzatori.

0

Se è necessario impostare una proprietà, quindi vorrei andare per la via di Vadian. Ma il tuo codice di installazione richiede alcune procedure come preparare direttamente la struttura complessa o preparare le cache di immagini, quindi mi piace andare per il trucco di chiusura lazy var. Questa chiusura di installazione viene eseguita una sola volta, proprio come qualsiasi altra proprietà lazy var viene inizializzata una volta. Quindi puoi scrivere codice procedurale abbastanza complesso qui. Non dimenticare di aggiungere private quindi le sottoclassi non interferiranno con la tua attività.

class MyViewController: NSViewController { 

    init() { 
     super.init(nibName: nil, bundle: nil)! 
     self.setup() 
    } 

    override init?(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { 
     super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) 
     self.setup() 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     self.setup() 
    } 

    override func encodeWithCoder(aCoder: NSCoder) { 
     super.encodeWithCoder(aCoder) 
    } 

    lazy private var setup:()->() = { 
     // do some complex procedure here!! 
     return {} 
    }() 
} 
+0

Grazie per il tuo suggerimento. Sono particolarmente interessato a come assegnare valori per consentire costanti, che devono essere eseguite all'interno di un metodo init. –

Problemi correlati