この記事は、2018/1/7に更新しました。
はじめに
今回のお題は、以前どうまずが投稿していた Objective-C 初心者あるあるトラブル対応 - Project Unknown をみて、確かにiOSの開発が慣れていないと、SIGABRT関連は大きな壁となるので、個人的に遭遇したSIGABRTやどう解決してきたかを記載しようと思います。
そもそもsignal SIGABRTって何よ?
バグとしか言いようが無いですね。 もうちょっと突っ込んで言うと、 シグナル(プロセス)が、abortする(中断する)事。 なので、原因は何?ってなると、色んなケースがあるので、特定するのは結構骨です。
ただ、もう数年iOS開発してきて、signal SIGABRTに陥るケースって大体似通って来ているので、その経験則を記載します。
その1 インターフェースビルダーとコードをOutlet引いたのに、そのOutletが外れてしまっているパターン
Objective-C 初心者あるあるトラブル対応 - Project Unknown でも書かれていますが、これが一番多いです。
なので、Outletを引いた際は、Xibをいじるとき、コードのOutletをいじる際はまず注意しましょう。
また弄った際は、右クリックで現在のOutletが表示されますので、確認する癖を付けると不具合に遭遇する確立がぐんと減ります。
(下のキャプチャは確認した際の例)
その2 配列で存在しない添字にアクセスしている。
signal SIGABRTの前で落ちるケースもありますが、これもなかなかあります。 原因を調査する際には、NSArray, NSDictionaryの前にもブレイクポイントを貼って確認してみましょう。
また、ブレイクポイントを該当配列の前に貼った場合、一度LLDBデバッガで中身にアクセス出来るか確認するのも良い手です。
以下のキャプチャでLLDBデバッガを用いて、値のチェックを行っています。
例では、配列ではなくて、UserDefaultsにデータが入っているかの確認を行います。
上記の様に、「po オブジェクト」とすることで、オブジェクトの中身を知ることが出来ます。
その3 オブジェクトが生成されていない
これは中々見つけるのがしんどいパターンです。 該当する処理を実行する際に、とあるオブジェクトが生成されているのが前提となっている場合、そのオブジェクトがnilだとsignal SIGABRTになったりします。
まぁ、そこの依存関係が無いようにクラス設計しろよって話かもですが、中々現実はうまいこと行きませんね。。。
こちらも、アタリを付けてブレイクポイントを貼って、LLDBデバッガでちゃんとオブジェクトが生成されているか確認するのが一番の近道かと思います。
その4 コード修正前の情報がキャッシュされてしまっている
特にリソース周りのxib等に多いです。
一回Outlet外して、build -> 再度接続 -> buildってやっても接続した事になっていない場合があります。
どうまずの記事にもありますが、一度Cleanすると治ったりします。
また、リソースだったりするとCleanだけだと治らない可能性があるので、リソース毎一度消すのもありです。
シミュレータとかでアプリを消すのでも良いですし、以下のキャプチャの様に、Optionを押しながらCleanでも同様の結果が得られます。
最後に
代表的なのは上記くらいでしょうか。 ほかは、CoreDataのFetchがキャッシュされているとか細かいのは沢山ありますが、 大体上記に集約されているかと思います。