2015-11-09 41 views
2

在這裏好幾個地方,有人建議,使用的NSDate的延伸內的計算機屬性可能一個好辦法,通過NSDateFormatter獲得日期的字符串版本,像這樣:如何在Swift類擴展中創建一個'static'?

extension NSDate { 
    public var UTC : String { 
     let formatter = NSDateFormatter() 
     formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ" 
     formatter.timeZone = NSTimeZone(abbreviation: "UTC") 
     return formatter.stringFromDate(self) 
    } 
} 

然而,分配NSDateFormatter是昂貴的,並且建議它們被創建一次並被緩存。每次日期格式化時,上面的代碼都會創建NSDateFormatter,我想知道是否有一種方法可以在擴展中創建一次NSDateFormatter以供重用?

很明顯,我可以在擴展名之外創建一次,但似乎打敗了表徵類的封裝。

我想起了:https://xkcd.com/1179/ !!

+1

Apple在https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html中說道:「以下類和函數通常不是線程安全的,在大多數情況下,你可以從任何線程使用這些類,只要你一次只從一個線程使用它們... NSDateFormatter ...「 –

+2

實際上,https://developer.apple.com/library/mac/documentation/ (1)在iOS 7和更高版本上NSDateFormatter是線程安全的, (2)在OS X v10上。(2)在OS X v10上安裝NSDateFormatter9和更高版本NSDateFormatter是線程安全的,只要您在64位應用程序中使用現代行爲,即可使用 ;(3)在早期版本的操作系統上,或者在使用舊格式化器行爲或在32位在OS X上,NSDateFormatter不是線程安全的,因此您不能同時從多個線程中變更日期格式化程序。 –

+0

很酷,謝謝@ ramsay諮詢。那是一種解脫。 –

回答

4

您可以將靜態成員添加到類擴展中,就像在類上一樣。您需要在使用它時將類名前綴添加到靜態成員名稱,例如NSDate.dateFormatterUTC,即使你在同一個班級使用它。

這工作:

extension NSDate { 
    private static let dateFormatterUTC: NSDateFormatter = { 
     let formatter = NSDateFormatter() 
     formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ" 
     formatter.timeZone = NSTimeZone(abbreviation: "UTC") 
     return formatter 
    }() 

    public var UTC : String { 
     return NSDate.dateFormatterUTC.stringFromDate(self) 
    } 
} 

它也不是世界上最糟糕的事情只是使用私人常數:

private let dateFormatterUTC: NSDateFormatter = { 
    let formatter = NSDateFormatter() 
    formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ" 
    formatter.timeZone = NSTimeZone(abbreviation: "UTC") 
    return formatter 
}() 

extension NSDate { 
    public var UTC : String { 
     return dateFormatterUTC.stringFromDate(self) 
    } 
} 

這不是比靜態類成員顯著更糟,因爲斯威夫特的private文件私人,而不是類型私人dateFormatterUTC這兩個聲明具有相同的範圍。即使在第一個例子中,NSDate.dateFormatterUTC在整個聲明的文件中都是可訪問的。

我確實同意靜態版本更可取,但僅限於文體原因:我喜歡它的縮進方式,它。

由於Gwendal wisely notes above,此方法假設UTC將永遠只能從一個線程調用。儘管static let和全局let在Swift中都是線程安全的, NSDateFormatter類不是! 看起來像it’s threadsafe starting in iOS 7。唷。

不過,在任何提及單身人士旁邊總是保持線程安全警告。如果您確實想要使用來自多個線程的非線程安全幫助程序對象,請考慮在每次調用時創建一個新的幫助程序,或者使用NSThread.currentThread().threadDictionary來創建每個線程實例。在選擇更復雜的線程本地選項之前,一定要做一點分析以確保實際解決性能問題。

+0

智慧在StackOverflow上豐富!我是「風格理由」的忠實粉絲,所以我也喜歡靜態版本。非常感謝Gwendal和Paul .. –

+0

Ramsay諮詢公司確實爲Apple提供了一個關於NSDateFormatter線程安全性的更準確的鏈接[#comment55020759_33602923]。 –

+0

很高興知道!更新的答案反映了這一點。 –

相關問題