LoginSignup
1
2

More than 5 years have passed since last update.

Swift4にあげたらNSExpressionのCustom Functionが動かなくなった

Last updated at Posted at 2017-09-25

Swift4にあげたら、NSExpressionのCustom Functionがunrecognized selector sent to instanceになって動かなくなったのでメモ。

NSExpressionのCustom Functionについて

NSExpressionでは以下のように文字列を計算できます。

let exp = NSExpression(format: "FUNCTION((10.0*pi*t), \'cos\')*FUNCTION((0.1*pi*t), \'cos\')")
let elements = ["pi" : Double.pi, "t" : 1.0]
exp.expressionValue(with: elements, context: nil) as? Double //0.951056516295154

このFUNCTION()で囲まれているところがCustom Functionになります。
以下のようにNSNumberを拡張してCustom Functionを作れます。(以下はSwift3でのコード)

public extension NSNumber{
    func tan() -> NSNumber{
        return NSNumber(value: Darwin.tan(self.doubleValue))
    }

    func sin() -> NSNumber{
        return NSNumber(value: Darwin.sin(self.doubleValue))
    }

    func cos() -> NSNumber{
        return NSNumber(value: Darwin.cos(self.doubleValue))
    }

    func atan() -> NSNumber{
        return NSNumber(value: Darwin.atan(self.doubleValue))
    }

    func square() -> NSNumber{
        return NSNumber(value: self.doubleValue * self.doubleValue)
    }
}

発生した問題

先にあげた例のような式だと、

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber cos]: unrecognized selector sent to instance

と出てcosという関数がないと実行時エラーが出ます。

解決方法

NSNumberのextensionの前に@objcを入れるだけ。

@objc
public extension NSNumber{

    ・・・

selector周りでobjcをつけないといけないことは知ってましたが、まさかここまで飛び火するとは。Objective-Cはあまり知らないんですよね。

もしかしたら、この先動かないところが出た時、NSが付いていたらこれと同じような方法で解決できるかもしれません。

終わり

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2