32
33

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.

Swiftのクラスの一番最初のプロパティを非ObjCの型にするとEXC_BAD_ACCESSする件

Last updated at Posted at 2016-03-26

ちょっと怖すぎんだろうと思ったので記事にします。
なお、このバグはこちらでレポートされています。
https://bugs.swift.org/browse/SR-1055

発生している問題

サンプルコードはこちらです。https://github.com/fmtonakai/SwiftPropertyCrash7_3

Swiftで次のようなクラスを定義します。

enum MyEnum {
  case Foo
}

class MyObject: NSObject {
  let myEnum: MyEnum = .Foo
}

これを利用すると実行時にクラッシュします。

スクリーンショット 2016-03-26 15.31.49.png

なお、ObjCとSwiftの混合プロジェクトで実行してますが、Swift onlyのプロジェクトでも同様にクラッシュが発生します。

回避方法

なんでもいいのでmyEnumの前にObjCからアクセスできるプロパティを設定します。もしくはプロパティの順番を変えて最初にObjCからアクセスできるものを一番最初に持ってきます。(どういうことなの・・・)

class MyObject: NSObject {
    let str = "str"
    let myEnum: MyEnum = .Foo
}

対策

自分のアプリがクラッシュするかを調べる

実行時エラーであり、問題のあるクラスを生成した時にクラッシュするので、アプリのどこでクラッシュが起こるかわかりません。アプリの中に爆弾を抱えた状態になります。

ここで、アプリがこれによってクラッシュするかを検出する方法があります。
それはObjC runtime関数のobjc_copyClassListを呼ぶことです。

スクリーンショット 2016-03-26 15.46.18.png

このように問題のあるクラスがあるとobjc_copyClassListでBAD_ACCESS起こすので、この問題を引き起こすクラスがあることを検出できます。クラッシュしなければとりあえず安心です。(がこれから作るクラスには十分注意してください)

クラッシュを引き起こすクラスを探す

クラッシュした場合、問題のあるクラスを探す必要があります。その時、この方法が便利です。
環境変数にOBJC_PRINT_CLASS_SETUP: YESを設定します
スクリーンショット 2016-03-26 16.01.02.png
すると起動時にObjCのクラスのセットアップがトレースされますが、問題のあるクラスがあった場合、そこでトレースが止まります。

クラッシュ時のログ

objc[24395]: CLASS: realizing class 'PropertyCrash.MyObject'  0x1002b0ec8 0x1002aff18
objc[24395]: CLASS: realizing class 'PropertyCrash.MyObject' (meta) 0x1002c5a88 0x1002afe88
objc[24395]: CLASS: methodizing class 'PropertyCrash.MyObject' (meta)

正常時のログ

objc[24453]: CLASS: realizing class 'PropertyCrash.MyObject'  0x1002b0f30 0x1002aff80
objc[24453]: CLASS: realizing class 'PropertyCrash.MyObject' (meta) 0x1002c5af8 0x1002afe88
objc[24453]: CLASS: methodizing class 'PropertyCrash.MyObject' (meta)
objc[24453]: CLASS: methodizing class 'PropertyCrash.MyObject' 

methoding classが2度行われないクラスが問題のあるクラスとわかります。

まとめ

早くHotfix出てくれー!つらい・・・

32
33
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
32
33

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?