なるようになるかも

力は多くの場合、その人の思いを超えない。

NSUnit と NSMeasurement についての話。

iOS10.0 / OS X 10.12 / tvOS 10.0 / watchOS 3.0 で追加されたクラスです。(これをひとまとめにする呼び方がほしい)

NSUnit は単位を表すクラスです。単位と double の値を組み合わせて、NSMeasurement、測定値を記述することができます。

NSMeasurement は加算・減算のメソッドがあるほか、乗算・除算の演算子オーバーロードがあるので、例えば時間の計算を以下の記述で行うことができます。

// Swift3 で書く場合には、`NS` が drop されるので、以下はそのように記述します
let sec = Measurement(value: 1.0, unit: UnitDuration.seconds)
let hour = Measurement(value: 1.0, unit: UnitDuration.hours)

let time = 2 * hour + 3 * sec;

この結果は、7203 sec になります。2時間と3秒の合計なので、7203秒であってますね。

これを Objective-C で書こうとすると、

NSMeasurement<NSUnitDuration *> *hour = [[NSMeasurement alloc] initWithDoubleValue:1.0 unit:NSUnitDuration.hours];
NSMeasurement<NSUnitDuration *> *minute = [[NSMeasurement alloc] initWithDoubleValue:1.0 unit:NSUnitDuration.minutes];
        
NSMeasurement<NSUnitDuration *> *computed = [hour measurementByAddingMeasurement:minute];

こんな記述になる上に、乗算のメソッドがなくて詰みます。

Xcode8 beta1 において、Objective-C 側では未実装で、nil が返ってきていました。Swift 側が先行して実装されており、Objective-C で書かれた Foundation のエクスポートではない?という推察ができます。

現時点でも NSUnit のサブクラスである NSDimension にはかなりの数が用意されていて、角度、面積、速度、質量濃度、分散、電気量、電圧、電流、電気抵抗、熱量、周波数、燃費、光量、距離、重量、電力、圧力、音量、温度があるっぽいです。

更にそれぞれの NSDimension は距離であれば「メートル」「ヤード」「ポンド」みたいな単位を持っています。単位に値を紐付けたものが、NSMeasurement ですので、上に示したコードのように「時間」と「秒」ということなるディメンションを持つ測定値で四則演算や比較を行ったり、NSUnitConverter で「ジュール」から「カロリー」に変換することができるというコンセプトなのだと思います。

さらに、NSMeasurementFormatter によって、ローカライズされた文字列を表示できるのです。

以下、初期の Xcode8 beta1 におけるバグについて書いてありましたが、現在は修正されているので削除。