13
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

オールアバウトAdvent Calendar 2016

Day 24

Objective-CからSwiftへの移行でバグりやすいポイント

Last updated at Posted at 2016-12-23

最近はSwift2.*→3の移行で非常に苦しんでいるエンジニアの方も多いかと思いますが、まずはObjective-C(以下obj-c)からSwiftへの移行で不具合が発生しやすいポイントをまとめてみました。気づき次第追記したいと思います。他にもあればコメントも大歓迎です :smile:

Optional関連

意図せずwrapされた値を使用してエラー

Intが入っていると思っていたのに、optional(10) のように余計な文字列が含まれている場合があります。optionalで定義した値の場合、unwrapしないと想定した値にならず、思わず不具合を引き起こす恐れがあります。

var badgeCount: Int?
badgeCount = 5
print("\(badgeCount)") // Optional(5)が出力され、警告も出ない

意図しないnil

obj-cの時はnilの値が入っていた場合は基本的にクラッシュはせず処理が続行されていましたが、Swiftの場合Xcodeが補完してくれるがままにunwrapなどしていると、nilが入ってアプリが意図せずクラッシュするという問題に遭遇すると思います。obj-cの時以上に、どのような値が入るかを想定する必要がありそうです。

下記例では、recordクラスのnameというメンバがnilを許可していて、labelにnameをセットするタイミングでunwrapするとエラーが発生する。

let apiClient = ApiClient()
let response = ApiClient().fetchHogeData()
let record = response.records[0]
label.text = record.name! //エラー発生

型の制約

obj-cでは数値といえば、NSInteger/NSUInteger/NSNumberなど種類が多かったと思いますが、swiftの場合は基本的にIntを使うことが多いかと思います。しかし、両言語が混在していて、Swift→objcに渡す場合はNSIntegerなどにcastする必要があります。Swift単体の場合はあまり意識しなくて良いかもしれませんが、移行過程などでは注意する必要がありそうです。

let memberID: Int = 50
let objcClass = objcClass() // memberIDというNSUIntegerのメンバ変数を持っているとする
objcClass.memberID = UInt(memberID) // memberIDをそのまま渡すとエラーになるのでUIntでキャストする必要がある

obj-cでSwiftのクラスを使う場合の制約

obj-cでswiftのクラスを使う場合は、swiftのクラスがNSObjectを継承している必要があります。

moduleのimportでの不具合

スクリーンショット 2016-12-22 16.26.11.png
今までcocoapodsなどのライブラリを使用する場合は、特定の.hファイルをimportしていたと思いますが、swiftからはモジュール指定でimportすることになります。しかし上記のようにimportの候補に表示されるものの、打ち消し線がでているので使えないかと思いきや、特に問題なく使えてしまいます。下記の記事によるとXcodeのバグではないかとコメントされていますが、なんだか気持ちが悪いですね。。
http://stackoverflow.com/questions/36463653/what-is-this-red-line-through-the-xcode-import-auto-suggest

まとめ

Swiftなり色々とすっきりと記述できるようになった反面、obj-cの時と比べると型に関しては厳格になりました。特にXcodeの表示されるunwrap関連の警告を、あまり理解せず"?"や"!"を付けて進めていないでしょうか?特にobj-cとswiftが混在してしまうコードの場合、どうしてもOptional属性をうまく使いながら実装をする必要があります。きちんと理解した上で適切な属性を使ってコードを書かないと後から痛い目に遭いますので、気をつけましょう :sweat_smile:

参考

どこよりも分かりやすいSwiftの"?"と"!"
Swift3のIUO(!)型から属性への変更に考えさせられたこと

13
9
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
13
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?