melvitax/DateHelper

Caching of formatter doesn't work

Vasant-Patel opened this issue · 5 comments

        let locale = Locale(identifier: "en_US_POSIX")

        let str = "2017-07-19T14:32:20.000+03:00"

        let format = "yyyy-MM-dd\'T\'HH:mm:ss.SSSZ"

        let d1 = Date(fromString: str, format: .custom(format), locale: locale)

        let d2 = Date(fromString: str, format: .custom(format), locale: locale)

        print(d1)
        print(d2)

Put the breakpoint at cachedFormatter, it always tries to create a new formatter and cached formatters is always empty

Now looking at the code makes it clear why it never caches

private static func cachedDateFormatters() -> [String: DateFormatter]

Function return value type which basically means that its trying to add a cache to a locally scoped dictionary which is destroyed as soon as the function returns

So neither of the cachedFormatter(....) function are able to actually save the newly created formatter :)

Nice find. Fixed in latest release. Thanks!

No its not fixed!

  • How were you able to come to a conclusion that you fixed it? Did you write a test? or try to test in any way? Did you use the snipped above that I posted?

  • You are again creating a local copy of cachedDateFormatters, which is basically the same as calling a function that returns value type

var formatters = Date.cachedDateFormatters

  • Please use Date.cachedDateFormatters directly instead of assigning to a local variable which will be destroyed as soon as scope ends

  • You can verify this local scope and the fact that its not pointing to the same address by printing the memory address

        var formatters = Date.cachedDateFormatters
        withUnsafePointer(to: &formatters) {
            print("local formatters \(formatters) has address: \($0)")
        }
        withUnsafePointer(to: &Date.cachedDateFormatters) {
            print("static formatters \(Date.cachedDateFormatters) has address: \($0)")
        }

How I tested: I put a break in if let cachedDateFormatter = formatters[hashKey] . It was always returning false since it was not caching. I changed cachedDateFormatter into a static variable and now the if statement returns true after the first one. You are correct about still creating a copy of the value but that is a different issue than not caching. Next time a well documented pull request would be more helpful than snarky remarks,

Apologies if that seemed snarky, I just wanted to know how it was tested since it doesn't work as its still setting the cache to local variable.

I will do a pull request tomorrow .. :)