A potentially dumb questions about swift (and dateFormatters)

I seem to recall hearing that DateFormatters are (or were) expensive to instantiate.
With this in mind, I tried a small experiment with the following code:

Code Block
class MyClass {
static let df = DrawingCellView.dateFormatter
    static var dateFormatter: DateFormatter {
        let result = DateFormatter()
        result.dateFormat = "yyyy-MM-dd"
        return result
    }
func dateText() -> String {
return MyClass.dateFormatter.string(from: Date())
}

When I put a breakpoint in the dateFormatter code, it fires each time I use it. However if I instead use df, the breakpoint only fires once.
Does this make sense?
If so, is this the recommended way to construct a runOnce static constant declaration/assignment?
thanks!
Mike
Answered by OOPer in 655350022

Does this make sense?

YES.

In your code, df is a stored property. So, the initial value of the declaration (DrawingCellView.dateFormatter) is called only once at the first time when df is used.

On the other hand, dateFormatter is a computed property. You see there is no = between dateFormatter: DateFormatter and {. The body of a computed property is called at each time the property is used.

If so, is this the recommended way to construct a runOnce static constant declaration/assignment?

I would declare the dateFormatter as follows and use it:
Code Block
class MyClass {
static let dateFormatter: DateFormatter = { //<- There is `=` here
let result = DateFormatter()
result.dateFormat = "yyyy-MM-dd"
        result.locale = Locale(identifier: "en_US_POSIX")
return result
}() //<- And there is `()`
func dateText() -> String {
return MyClass.dateFormatter.string(from: Date())
}
//...
}

With this declaration, dateFormatter becomes a stored property and the initial value ({ ... }()) is called only once.

(You should better set locale of the DateFormatter when you use it with fixed format in dateFormat.)
Accepted Answer

Does this make sense?

YES.

In your code, df is a stored property. So, the initial value of the declaration (DrawingCellView.dateFormatter) is called only once at the first time when df is used.

On the other hand, dateFormatter is a computed property. You see there is no = between dateFormatter: DateFormatter and {. The body of a computed property is called at each time the property is used.

If so, is this the recommended way to construct a runOnce static constant declaration/assignment?

I would declare the dateFormatter as follows and use it:
Code Block
class MyClass {
static let dateFormatter: DateFormatter = { //<- There is `=` here
let result = DateFormatter()
result.dateFormat = "yyyy-MM-dd"
        result.locale = Locale(identifier: "en_US_POSIX")
return result
}() //<- And there is `()`
func dateText() -> String {
return MyClass.dateFormatter.string(from: Date())
}
//...
}

With this declaration, dateFormatter becomes a stored property and the initial value ({ ... }()) is called only once.

(You should better set locale of the DateFormatter when you use it with fixed format in dateFormat.)
Thanks OOPer, that is exactly the answer I was looking for.
(and fair point about the 'lazy' configuration of the DateFormatter :-)
A potentially dumb questions about swift (and dateFormatters)
 
 
Q