ios - Is caching a NSDateformatter application-wide good idea? -


it's well known creating nsdateformatters 'expensive'

even apple's data formatting guide (updated 2014-02) states:

creating date formatter not cheap operation. if use formatter frequently, typically more efficient cache single instance create , dispose of multiple instances. 1 approach use static variable.

but doc seems not date swift , can't find in latest nsdateformatter class reference caching formatter can assume it's expensive swift objective-c.

a lot of sources suggest caching formatter inside class using it, example controller or view.

i wondering if handy or 'cheaper' add singleton class project store datepicker you're assured it's never necessary create again. used everywhere in app. create several shared instances containing multiple datepickers. example 1 datepicker displaying dates , 1 time notation:

class dateformattermanager {     var formatter = nsdateformatter()      class var dateformatmanager : dateformattermanager {         struct static {             static let instance : dateformattermanager = dateformattermanager()         }         // date shown date in tableviews         static.instance.formatter.dateformat = "yyyy-mm-dd"         return static.instance     }      class var timeformatmanager : dateformattermanager {         struct static {             static let instance : dateformattermanager = dateformattermanager()         }         // date shown time in tableviews         static.instance.formatter.dateformat = "hh:mm"         return static.instance     }      // mark: - helpers     func stringfromdate(date: nsdate) -> string {         return self.formatter.stringfromdate(date)     }     func datefromstring(date: string) -> nsdate? {         return self.formatter.datefromstring(date)!     } }  // usage like:  dateformattermanager.dateformatmanager.datefromstring("2014-12-05") 

another likewise approach creating 1 singleton , switching format depending on need:

class dateformattermanager {     var formatter = nsdateformatter()      var dateformatter : nsdateformatter{         {             // date shown date in tableviews             formatter.dateformat = "yyyy-mm-dd"             return formatter         }     }      var timeformatter : nsdateformatter{         {             // date shown time in tableviews             formatter.dateformat = "hh:mm"             return formatter         }     }      class var sharedmanager : dateformattermanager {         struct static {             static let instance : dateformattermanager = dateformattermanager()         }         return static.instance     }      // mark: - helpers     func datestringfromdate(date: nsdate) -> string {         return self.dateformatter.stringfromdate(date)     }     func datefromdatestring(date: string) -> nsdate? {         return self.dateformatter.datefromstring(date)!     }     func timestringfromdate(date: nsdate) -> string {         return self.timeformatter.stringfromdate(date)     }     func datefromtimestring(date: string) -> nsdate? {         return self.timeformatter.datefromstring(date)!     } }  // usage like:  var dateformattermanager.sharedmanager.datefromdatestring("2014-12-05") 

would either of or horrible idea? , switching format expensive?

update: hot licks , lorenzo rossi point out, switching formats not such idea (not thread safe , expensive re-creating..).

i'll chime in here answer based on experience. answer yes, caching nsdateformatter app-wide idea, however, added safety there step want take this.

why good? performance. turns out creating nsdateformatters slow. worked on app highly localized , used lot of nsdateformatters nsnumberformatters. there times dynamically created them greedily within methods having classes had own copy of formatters needed. in addition, had added burden there cases display strings localized different locales on same screen. noticing our app running slow in cases, , after running instruments, realized formatter creation. example saw performance hit when scrolling table views large number of cells. ended caching them creating singleton object vended appropriate formatter.

a call like:

nsdateformatter *dateformatter = [[formattervender sharedinstance] shortdate]; 

note, obj-c, equivalent can made in swift. happened ours in obj-c.

as of ios 7, nsdateformatters , nsnumberformatters "thread safe", hot licks mentioned, don't want go around modifying format if thread utilizing it. +1 caching them.

and benefit thought of code maintainability. if have large team have. because devs know there centralized object vends formatters, can see if formatter need exists. if doesn't, gets added. typically feature related, , hence means new formatter needed elsewhere well. helps reduce bugs, because if there happens bug in formatter, fix 1 spot. catch during unit tests new formatter.

there 1 more element can add safety, if want. can use nsthread's threaddictionary store formatter. in other words, when call singleton vend formatter, class checks current thread's threaddictionary see if formatter exists or not. if exists, returns it. if not, creates , returns it. adds level of safety if, reason wanted modify formatter, can , not have worry formatter being modified thread.

what used @ end of day singleton vended specific formatters (both nsdateformatter , nsnumberformatter), ensuring each thread had it's own copy of specific formatter (note app created prior ios 7, made essential thing do). doing improved our app performance got rid of nasty side effects experienced due thread safety , formatters. since have threaddictionary part in place, never tested see if had issues on ios7+ without (ie. have become thread-safe). why added "if want" above.


Comments

Popular posts from this blog

python - mat is not a numerical tuple : openCV error -

c# - MSAA finds controls UI Automation doesn't -

wordpress - .htaccess: RewriteRule: bad flag delimiters -