私はSwiftに不慣れで、Objective-Cに慣れていません。誰かがこれをSwiftに変換するのを手伝ってくれませんか?このコードは、Ray WenderlichのiOSのベストプラクティスから入手しました- http:/ /www.raywenderlich.com/31166/25-ios-app-performance-tips-tricks
このコードをどこに配置しますか?グローバル変数でいっぱいのクラスファイルに入れますか?
- (NSDateFormatter *)formatter {
static NSDateFormatter *formatter;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_formatter = [[NSDateFormatter alloc] init];
_formatter.dateFormat = @"EEE MMM dd HH:mm:ss Z yyyy"; // Twitter date format
});
return formatter;
}
質問のメソッドに直接類似したものを本当に探している場合は、Swift 3で、次のようにすることができます。
_class MyObject {
// define static variable
private static let formatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "EEE MMM dd HH:mm:ss Z yyyy"
return formatter
}()
// you could use it like so
func someMethod(date: Date) -> String {
return MyObject.formatter.string(from: date)
}
}
_
またはSwift 2:
_class MyObject {
// define static variable
private static let formatter: NSDateFormatter = {
let formatter = NSDateFormatter()
formatter.dateFormat = "EEE MMM dd HH:mm:ss Z yyyy"
return formatter
}()
// you could use it like so
func someMethod(date: NSDate) -> String {
return MyObject.formatter.stringFromDate(date)
}
}
_
グローバルのようなstatic
プロパティは、デフォルト値に対して_dispatch_once
_の動作をお楽しみください。詳細については、AppleのSwiftブログの Files and Initialization エントリの最後にある_dispatch_once
_の説明)を参照してください。
日付フォーマッタのベストプラクティスについては、次のことをお勧めします。
はい、再度必要になる可能性が高いフォーマッタを不必要に作成および破棄しないことが賢明です。 WWDC 2012ビデオ iOS App Performance:Responsiveness 、Appleは明示的に
日付形式ごとに1つのフォーマッターをキャッシュします。
_NSLocale.currentLocaleDidChangeNotification
_のオブザーバーをSwift 3(NSCurrentLocaleDidChangeNotification
in Swift 2)からNSNotificationCenter
を介して追加し、これが発生した場合、キャッシュされたフォーマッタをクリア/リセットします。
フォーマットのリセットには再作成と同じくらいのコストがかかるため、フォーマッターのフォーマット文字列を繰り返し変更しないでください。
結論として、同じ日付フォーマットを繰り返し使用している場合は、可能な限り日付フォーマッターを再利用してください。
NSDateFormatter
を使用して日付文字列を解析し、Webサービスと交換する(またはデータベースに保存する)場合、_en_US_POSIX
_ロケールを使用して、グレゴリオ暦を使用していない可能性のある国際ユーザーの問題を回避する必要があります。 Apple Technical Q&A#148 を参照してください。 (またはiOS 10およびmacOS 10.12では、_ISO8601DateFormatter
_を使用します。)
ただし、dateFormat
をNSDateFormatter
/DateFormatter
とともに使用する場合は、現在のロケールを使用して文字列を作成し、エンドユーザーに提示しますが、作成時には_en_US_POSIX
_ localを使用します/アプリ内で内部的に使用される、またはWebサービスと交換される解析文字列。
ユーザーインターフェイスの日付文字列をフォーマットする場合は、可能であればdateFormat
に文字列リテラルを使用しないようにして、文字列をローカライズしてください。可能な場合はdateStyle
およびtimeStyle
を使用してください。また、カスタムdateFormat
を使用する必要がある場合は、テンプレートを使用して文字列をローカライズしてください。たとえば、_E, MMM d
_をハードコーディングするのではなく、Swift 3では、dateFormat(fromTemplate:options:locale:)
を使用します。
_formatter.dateFormat = DateFormatter.dateFormat(fromTemplate: "EdMMM", options: 0, locale: Locale.current)
_
またはSwift 2、dateFormatFromTemplate(_:options:locale:)
:
_formatter.dateFormat = NSDateFormatter.dateFormatFromTemplate("EdMMM", options: 0, locale: NSLocale.currentLocale())
_
これにより、たとえば、米国のユーザーの場合は「Mon、Sep 5」、英国のユーザーの場合は「Mon 5 Sep」が自動的に表示されます。
NSDateFormatter
は、iOS 7以降とmacOS 10.9以降で実行されている64ビットアプリでスレッドセーフになりました。
Rob が言ったように、DateFormatterを作成するパフォーマンスには注意が必要です。そのWWDCセッションのヒントを使用してください。
私はこれをNSDateとNSDateFormatterの拡張として行っています(Swift 2、3、4でテストされたコード):
extension NSDate {
func PR2DateFormatterUTC() -> String {
return NSDateFormatter.PR2DateFormatterUTC.stringFromDate(self)
}
//... more formats
}
extension NSDateFormatter {
fileprivate static let PR2DateFormatterUTC: NSDateFormatter = {
let formatter = NSDateFormatter()
let timeZone = NSTimeZone(name:"UTC")
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
formatter.timeZone = timeZone
return formatter
}()
//... more formats
}
使用法:
let dateStringUTC = NSDate().PR2DateFormatterUTC()
私は見つかったシングルトンアプローチ here を適用しようとしました。これにより、アプリケーション内で使用するさまざまな形式でロードできるシングルトンが作成されます。たとえば、formatter.fromDateTime(myString)
を使用して、アプリケーションの任意の場所にアクセスできます。
let formatter = FormatterFormats()
class FormatterFormats {
var dateTime: NSDateFormatter = NSDateFormatter()
class var sharedInstance:FormatterFormats {
return formatter
}
func fromDateTime(dateString: String) -> NSDate {
return dateTime.dateFromString(dateString)!
}
init() {
dateTime.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
}
}
そのようにして、NSDateFormatter
とonceToken
を関数の外に移動できます。次に、あなたの例のようにそれを行うことができます:
var theFormatter:NSDateFormatter!
var token: dispatch_once_t = 0
func formatter() ->NSDateFormatter {
dispatch_once(&token) {
theFormatter = NSDateFormatter()
theFormatter.dateFormat = "EEE MMM dd HH:mm:ss Z yyyy"
}
return theFormatter
}
しかし David が示唆するように、d ispatch_once singleton question を確認する必要があります。