iOSエンジニアのつぶやき

毎朝8:30に iOS 関連の技術について1つぶやいています。まれに釣りについてつぶやく可能性があります。

Extension でのインスタンスの取り扱いに注意する

今回は以前書いた下記の記事で、アプリのパフォーマンスをさらにあげるための方法を簡単に紹介したいと思います。

yamato8010.hatenablog.com

改善方法

整数に3文字区切りのカンマをつけた文字列を返すプロパティを以前は下記のような形で書きました。

extension UInt {
    var withCommaString: String {
        let numberFormatter = NumberFormatter()
        numberFormatter.numberStyle = .decimal
        numberFormatter.groupingSeparator = ","
        numberFormatter.groupingSize = 3

        return numberFormatter.string(from: NSNumber(value: self)) ?? "\(self)"
    }
}

仮に、下記のようなメソッドを用意して 10,000 件のデータをコンバートした場合は、同じ NumberFormatter() インスタンス が 10,000 件生成されることになります。特に Formatterインスタンスを生成するコストは高いのでなるべくインスタンスを使いまわした方がパフォーマンスは向上します。

func getPriceList(source: [UInt]) -> String {
    return source.map { $0.withCommaString }
}

そして修正したコードがこちらになります。static let を用いることで遅延初期化され、呼び出し毎に初期化されることがなくなります。

extension UInt {
    private static let numberFormatter: NumberFormatter = {
        return NumberFormatter()
    }()
    var withCommaString: String {
        UInt.numberFormatter.numberStyle = .decimal
        UInt.numberFormatter.groupingSeparator = ","
        UInt.numberFormatter.groupingSize = 3

        return UInt.numberFormatter.string(from: NSNumber(value: self)) ?? "\(self)"
    }
}

参考

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html#//apple_ref/doc/uid/TP40002369-SW12

medium.com

その他の記事

yamato8010.hatenablog.com

yamato8010.hatenablog.com

yamato8010.hatenablog.com