Objective-Cの@property
で定義されたプロパティをSwiftから扱うときに知識不足で少し失敗したので、調べてみました。
間違い等があれば、ご指摘ください
失敗内容
- SwiftからObjective-Cのプロパティ(
nullability annotation
なし)を使用 - Swiftで
implicitly unwrapped optional
な型に変換されたプロパティをそのまま使用 -
implicitly unwrapped optional
に変換されたObjective-Cの値がnilってることが原因で実行時エラー
結論
-
nullability annotation
を適切に使用してSwiftから呼ぶときにimplicitly unwrapped optional
を使わないようにする。 - 上記が難しい場合は
nullability annotation
を指定していないプロパティをSwiftから使うときには、nilチェックをする。(ちょっと気持ち悪い)
nullability annotation
を指定していないプロパティをSwiftから使う
nullability annotation
とは?
nullability annotation
とは、Objective-Cのプロパティにつけられるnullable
やnonnull
といった属性になります。(詳しくはこちら)
nullability annotation
がついたプロパティをSwiftから見ると?
Objective-Cのコードにて適切にnullability annotation
が使用されている場合にSwiftでそのプロパティを使用するとどのように扱われるのでしょうか?
なんとなく想像できるかと思いますが、
-
nullable
はOptionalでwrapされた型 -
nonnull
は非Optionalな型
としてSwiftで扱うことができます。
[Objective-C]
@property (nullable) id nullableProperty;
@property (nonnull) id nonNullProperty;
[Swift]
var nullableProperty: AnyObject?
var nonNullProperty: AnyObject
nullability annotation
がついていないプロパティをSwiftから見ると?
次に、nullability annotation
が使用されていないプロパティをSwiftから扱うときにはどうなるか見てみます。
[Objective-C]
@property id unannotatedProperty;
[Swift]
var unannotatedProperty: AnyObject!
nullability annotation
が使用されていないと、**!
が付いています。これはimplicitly unwrapped optional
**と言うものです。
implicitly unwrapped optional
の実体はOptionalですが、確実に値が入っているという前提で暗黙的にunwrapされて使用されます。
実体はOptionalなので、もしnilが入っていた場合は暗黙的なunwrapでエラーになります。
気をつけたい点
ここでObjective-Cから変換されたimplicitly unwrapped optional
のプロパティの扱いに注意が必要です。
implicitly unwrapped optional
なので値が入っているはずなのですが、場合によってはObjective-Cのコードにてnilが入っているということが起こりえます。
なので、通常のimplicitly unwrapped optional
よりも気をつけて扱わないと予期せぬ実行時エラーに遭遇する可能性があります。
結論(再掲)
もし、Objective-Cから呼んだプロパティがimplicitly unwrapped optional
になっていたら以下のように対応するのが良さそうです。
-
nullability annotation
を適切に使用してSwiftから呼ぶときにimplicitly unwrapped optional
を使わないようにする。 - 上記が難しい場合は
nullability annotation
を指定していないプロパティをSwiftから使うときには、nilチェックをする。(ちょっと気持ち悪い)
終わりに
結論にも書いた通り、Objective-C側で適切にnullability annotation
を使うことでSwiftと連携したときに安全なコードが書けそうです。
参考
- https://developer.apple.com/library/prerelease/content/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html#//apple_ref/doc/uid/TP40014216-CH4-ID45
- https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-ID334
- http://developer.wonderpla.net/entry/blog/engineer/ObjC_Swift_Nullable/