16
16

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.

NSJSONSerializationの落とし穴

Last updated at Posted at 2013-06-15

落とし穴、というかパースする前にはnilチェックしましょうと言う話。

iOS5からJSONを便利に扱えるNSJSONSerializationクラスだが、JSONをパースするためのJSONObjectWithData:options:error:メソッドは、引数として渡すNSDataがnilだと例外を発生させる。

//パースさせたいNSDataがnilの場合例外が発生する
id jsonObject = [NSJSONSerialization JSONObjectWithData:nil
                                                options:NSJSONReadingAllowFragments
                                                  error:nil];

引数にNSErrorのアドレスを渡すことでエラーがセットされるが、これはあくまでパースエラーが起こった場合であり、パースさせたい対象がnilだとパースエラーではなく例外が発生するためにこのエラーでは判断できない。

例外が発生するのならばtry catchで囲むことを考える

id jsonObject;
@try {
    jsonObject = [NSJSONSerialization JSONObjectWithData:nil
                                                    options:NSJSONReadingAllowFragments
                                                      error:nil];
@catch (NSException *exception) {
    /*…*/
}

try catchにより例外発生時に強制終了することはなくなったが、nilの場合に例外が発生していると原因が特定されていて防げるのであれば、下記のようにnilチェックをするだけでよいのではないか

if (data) {
    id jsonObject = [NSJSONSerialization JSONObjectWithData:data
                                                    options:NSJSONReadingAllowFragments
                                                      error:nil];
  /*…*/
} else {
    /*…*/
}

また、try catchをあまり使いたくない理由としては、例外発生時にcatchできようが、tryのコードブロック(スコープ)を抜けてしまうことでコード末尾に辿りつけず、ARC使用時に自動で挿入されたreleaseが実行されないためメモリリークしてしまうため(そのような状況を防ぐにはLLVM コンパイラーのオプションとして "-fobjc-arc-exceptions" につけると良いらしい)。

参考

EZ-NET: 例外発生時の ARC 制御
http://program.station.ez-net.jp/special/objective-c/llvm/arc/exception.asp

Google Objective-Cスタイルガイド 日本語訳
http://www.textdrop.net/google-styleguide-ja/objcguide.xml#Avoid_Throwing_Exceptions

16
16
4

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
16
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?