你的日期实际上是一个computed property
只有一个,getter
所以它只能被阅读,而不是写.
相比之下,你FullDate
是一个stored property
.
computed properties
通常用于隐藏其他类的功能或以方便的方式暴露隐藏的数据.
下面是SomeClass
对象中的一些插图.
stored properties
只是普通的老房产
computed properties
是getters
也可能也是setters
.一个很好的例子是height
和width
的CGRect
,这些其实都是从CGRect.size
而是作为实现convenience getters
property observers
是stored properties
更改值时执行的函数.didSet
和willSet
access control
on get
并set
允许您stored properties
根据访问权限创建只读或写.
class SomeClass { // just a variable var storedProperty : Int = 10 // just a variable but the setter is hidden from other "files" private(set) var storedPropertyWithPartialAccessControl : Int = 0 // only calculates when set var derivedProperty : Int = 0 { didSet { storedProperty = doStuffs(derivedProperty) } } // calculates every get and set var computedProperty : Int { get { // get is needed return doStuffs(storedProperty) } set(value) { // set is not needed, using only get gives you a read only property storedProperty = doReverseStuffs(value) } } // hidden functions that are used in the computed property private func doStuffs(value:Int) -> Int { return value * 10 } private func doReverseStuffs(value:Int) -> Int { return value / 10 } }
因为NSDateFormatter
效率非常低,所以在它中使用它是非常糟糕的computed property
.每次获得都会创建一个.浪费了大量的时间和精力,因为结果值在大多数情况下可能是相同的.
最佳实践 :
使用computed properties
到get
stored properties
和set
做计算.
使用Singleton存储 NSDateFormatter
一个更好的方法:
class SomeEvent { // Store calculated results. // This is private to make the class cleaner in use. private var storedDate : NSDate? private var storedFormattedDate : String = "" // get returns stored values without calculations // set updates both stored values after calculations var date : NSDate? { get { return storedDate } set(value) { storedFormattedDate = format(date: value) storedDate = value } } var formattedDate : String { get { return storedFormattedDate } set(value) { storedDate = readDateFrom(dateString: value) storedFormattedDate = format(date: storedDate) } } // hidden functions, again to make the class cleaner in use. private func format(date maybeDate:NSDate?) -> String { guard let date = maybeDate else { return "" } guard let dateFormatter = MyDateFormatter.shared().dateFormatter else { return "" } return dateFormatter.stringFromDate(date) } private func readDateFrom(dateString string:String) -> NSDate? { // get detector if let detector = MyDateFormatter.shared().dateReader { // results let matches = detector.matchesInString(string, options: [], range: NSRange(location: 0, length: string.characters.count)) // first result if let match = matches.first, let date = match.date { return date } } // just format if there is no detector if let dateFormatter = MyDateFormatter.shared().dateFormatter { if let date = dateFormatter.dateFromString(string) { return date } } // everything failed return nil } }
单身人士存储NSDateFormatter
和NSDataDetector
:
谷歌: Swift Singleton
class MyDateFormatter { private static var privateShared : MyDateFormatter? var dateFormatter : NSDateFormatter? var dateReader : NSDataDetector? class func shared() -> MyDateFormatter { guard let uwShared = privateShared else { privateShared = MyDateFormatter() return privateShared! } return uwShared } class func destroy() { privateShared = nil } private init() { dateReader = try? NSDataDetector(types: NSTextCheckingType.Date.rawValue) dateFormatter = NSDateFormatter() dateFormatter!.dateFormat = "EEEE MMM dd" } }
测试:
let event = SomeEvent() event.formattedDate = "tomorrow" event.formattedDate // "Friday Dec 04" event.formattedDate = "25/02/2010" event.formattedDate // "Thursday Feb 25" event.formattedDate = "Sunday Mar 13" event.formattedDate // "Sunday Mar 13"