SwiftDate
SwiftDate copied to clipboard
Region object is not thread safe because it has NSCalendar
NSCalendar is not thread safe according to apple's document: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html
So Region and DateInRegion is also not thread safe. Is it expected..? If so I'd be better to be documented :)
Region is exposing mutable NSCalendar instance to public, so Region is mutable. Is it also expected..?
public let calendar: NSCalendar!
I worry about thread and mutability because I want to cache default Region object to memoize NSCalendar object.
New Region is created on each nsDateInstance.add(...)
and it impacts performance.
calendar
is defined as let and assigned at init time so it cannot be change further.
Yes, let calendar
cannot be changed. But NSCalendar itself is mutable class. For example, locale can be changed by region.calendar.locale = ...
from outside of the library.
yeah, you are right. So what do you think is the best approach? We can return a copy of the calendar var and keep it private. Any other solution?
We could create a new struct that mimics the data model of NSCalendar
. That would create a dependency from Apple's NSCalendar
class though. Your solution is easier.
On the other hand: Apple did the same with NSArray
and Array
: Swiftifying. Doing that with NSCalendar
to a Calendar
struct would imply A LOT of work though.
Wouldn't that be fun? :smile:
NSTimeZone is thread unsafe too...
Something like this?
protocol Calendarish {
public let identifier: String
public let locale: Locale
public let timeZone: TimeZone
...
}
struct GregorianCalendar : Calendarish {
...
}
struct TimeZone {
public let abbreviation String
public let GMTOffset NSTimeInterval
...
}
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html
NSTimeZone is thread safe according to the document.
struct that mimics the data model of NSCalendar
I agree with this, because only public constructor Region(calendarName:, timeZoneName:, localeName:)
does not depend on NSCalendar instance.
I'm a bit afraid to make another set of classes where the only scope is to avoid this issue; we will end with a big library of "non necessary things". We could hide the calendar inside our region and expose it as a copy; what's wrong with this propose?
Woops I looked in the wrong list and stand corrected. ;-)
@malcommac nothing wrong with your approach. I am just playing with the idea.
Is this an idea for making calendars thread safe?
yeah sure :) btw I can't see benefits; at the start of this project my idea is to completely hide the cocoa framework behind and make something with new structs and classes However a day you said to me we should keep things simple and in the majority of cases people love to use standard classes, so with SwiftDate you can still use NSDate and move on DateInRegion only if you need to play with a custom configuration. It was enlightening and now I think adding tons of "fake" classes only to hide a behaviour is not the best solution. I'm afraid of that.
@Hout We are using this for our NSDateFormatter object too!
I meant like below:
class Region {
let calendarName: CalendarName
let timeZoneName: TimeZoneName
let localName: LocaleName
var calendar: NSCalendar {
// It might be better to cache calendar per Region instance instead of global one.
return CalendarCache.sharedCalendarForCurrentThtread(region: self)
}
...
}
This does not create any new abstraction or mimics, and just make Region thread safe and cacheable..!
struct that mimics the data model of NSCalendar
Region is already mimics parameter of NSCalendar
@malcommac why aren't we as smart as @ypresto ? ;-)
Note that var calendar
is internal access, and cannot be manipulated from outside of ~~instance~~ library.
Cost of copying NSCalendar is not ignorable, so it'd be better to copy it only when necessary (for use from outside of the library).
public func newCalendar() -> NSCalendar {
...
}
@malcommac I think you are correct about the origins of your project and the decision direction.
I got carried away; give me a hint and I have a thousand ideas ;-) This Calendar idea originates from the expectation that over time the Cocoa classes will be Swiftified in the swift.org project. A new and open sourced Calendar struct would be an enlightment. It would be a project on its ownthough and way passed the principles of this project.
So how do we progress here?
I will take on this one with @ypresto 's idea for defining an immutable Region struct.
There is an accepted proposal for swift 3 that will make immutable Calendar
wrapper over NSCalendar
. It is better to wait for it, I think.
Great find Sergey! I agree to wait for Swift 3. Do you concur @malcolmmac?