質問: Objective-CのOSSをswiftから使用しようとしているのですが 「nonnull NSNumber *」の型が理解できずうまくいきません。。。 ``` CorePlot +(nonnull instancetype)plotRangeWithLocation:(nonnull NSNumber *)loc length:(nonnull NSNumber *)len; ``` 試行錯誤中しているのですが、理解できていない状態です。 なにかアドバイスがあると助かります。 ``` CPTPlotRange.plotRangeWithLocation(NSNumber(int: 0), length: NSNumber(int: 309)) ``` エラー内容 'plotRangeWithLocation(_:length:)' is unavailable: use object construction 'CPTPlotRange(location:length:)'
回答: SwiftでObjective-Cのクラスをimportする場合、クラスメソッドにはちょっとした例外事項があって、 * クラス名の末尾とクラスメソッド名の先頭の単語が一致する * メソッドの戻り値の型が`id`, `instancetype`, またはそのクラス型そのものである 場合には、クラスメソッドではなく、convenience initializerとしてimportされる。 ...と言うことになっています。 従って、`CPTPlotRange`クラスに ``` +(nonnull instancetype)plotRangeWithLocation:(nonnull NSNumber *)loc length:(nonnull NSNumber *)len; ``` なんてシグニチャーのクラスメソッドがある場合、Swiftにimportされた後は ``` class func plotRangeWithLocation(loc: NSNumber, length len: NSNumber) ``` と言うクラスメソッドとしてではなく、 ``` convenience init(location loc: NSNumber, length len: NSNumber) ``` と言うイニシャライザのつもりで呼び出してやらないといけません。 定数リテラルは自動的に`NSNumber`に変換されるので、呼び出す場合は、 ``` CPTPlotRange(location: 0, length: 309) ``` という感じになるでしょう。(もちろんイニシャライザですから、結果は何かの変数に代入するなりして使ってください。) `'plotRangeWithLocation(_:length:)' is unavailable: use object construction 'CPTPlotRange(location:length:)'`というメッセージは「'plotRangeWithLocation(_:length:)'(というクラスメソッドとしては)利用できない、オブジェクトコンストラクション(=イニシャライザ呼び出し)の'CPTPlotRange(location:length:)'の方を使え」と言う意味です。 最近のObjective-Cのコードには`nonnull`だの`_bridge`だの、解説記事を読んでもよくわからない修飾子が増えていて、ついそこがわからないせいでうまくいかないように思われたのかもしれませんが、`nonnull NSNumber *`は`null`(Swiftなら`nil`)にならないNSNumber型を表していて、Swiftでは(`NSNumber?`や`NSNumber!`ではなく)単に`NSNumber`型になると思って正解です。