Reputation:
How can I avoid repeating code between my initialisers? I want the dateFormatter to remain a let constant.
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)
}
Upvotes: 5
Views: 521
Reputation: 285064
If this is really the actual code replace the entire code with
lazy var dateFormatter : NSDateFormatter = {
let formatter = NSDateFormatter()
formatter.dateStyle = .MediumStyle
formatter.timeStyle = .MediumStyle
return formatter
}()
The variable is lazily initialized once when it's accessed the first time
Edit: It's also possible to declare the variable as constant without the lazy attribute.
let dateFormatter : NSDateFormatter = { ...
The difference is that the formatter is created immediately (not lazily) during the initialization of the instance.
Edit:
In Swift 3 NSDateFormatter
has been renamed to DateFormatter
and .MediumStyle
to .mediumStyle
Upvotes: 9
Reputation: 1637
If you need to setup a property, then I would go for vadian's way. But your setup code requires some procedure like preparing complex directly structure or preparing image caches, then I like to go for lazy var closure trick. This setup closure executes only once, just like any other lazy var properties are initialized once. So you can write pretty complex enough procedural code here. Don't forget add private
then your subclasses won't interfere your business.
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 {}
}()
}
Upvotes: 0
Reputation: 4544
In this case you could set the default property value of the date formatter using a closure.
Then your property declaration becomes:
let dateFormatter: NSDateFormatter = {
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = .MediumStyle
dateFormatter.timeStyle = .MediumStyle
return dateFormatter
}()
and you can remove the date formatter bits from your initialisers.
Upvotes: 3
Reputation: 4448
That's the only way I could think of:
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
}
}
Upvotes: 0