LoginSignup
24
18

More than 5 years have passed since last update.

Objective-Cでのエラー処理

Posted at

目的

どうやればいいか疑問だったため、まとめるのも兼ねて

基本

エラーに用いるオブジェクトは2つ

  • NSError
  • NSException

それぞれ詳しく見てみると

NSError

一般的なエラーはこれで扱う
プロパティは3つで

  • domain
  • code
  • userInfo

domain -> com.example.applicationのような識別子
code -> そのままエラーのコード
userInfo -> NSDictionaryを想定していて、NSLocalizedDescriptionKeyにエラーメッセージを設定する

使い方としては[NSError errorWithDomain:code:userInfo]を使って生成、
関数の返り値として用いるのが普通

NSException

プログラマのせいで起こるエラー
代表的なのは、不正なインデックスでNSArrayにアクセスした時のNSRangeExceptionなど

正常なApplicationの遷移の中で使用することは推奨されておらず、
リリース版では基本的にExceptionが生成されないようにしなければならない

このために@try @catch @finally構文も存在する

ライブラリ開発するときには、不正な操作に対して飛ばす感じになる?

実際のアプリケーション開発の中でのエラー処理

結論としては、NSErrorの生成、場合分けをラップして使うのがベストな気がするところ

多分こんな感じ

superClass

// Domain
static const NSString ERROR_DOMAIN = @"com.example.app";

@interface MyError
@property(strong, nonatmic)NSError *error;
-(instancetype)initWithCode:(NSInteger)code reason:(NSString *)reason;
-(void)showAlert;
@end

@implementation MyError

-(instancetype)initWithCode:(NSInteger)code reason:(NSString *)reason {
    self = [super init];
    if(!self) return nil;
    NSDictionary *info = @{@"NSLocalizedDescriptionKey": reason};
    _error = [NSError errorWithDomain:ERROR_DOMAIN code:code userInfo:info];
    return self;
}

@end
childClass
@implementation MyNetworkError

+(instancetype)init {
  self = [super initWithCode:100 reason:@"cant reach to server"];
  if(!self) return nil;
  return self;
};

/** 
 * こんなのあると便利かもしれない 
 * 他にもエラー関連の仕事などはこのクラスに実装してしまう
 **/
-(PMKPromise *)showAlert {
  // メッセージ等適当に設定してアラート出す
  // Promiseで押されたインデックス等の情報を返す
}

// こういうのとかも
-(void)log {
  NSLog(@"%@", _error);
}

@end

エラーコードとかベタ書きする実装もなくはないが、
- 際限なし膨らむ (ので見通し悪い
- エラーオブジェクトに仕事させられない
- 判断のifがひたすら増える

等あるのでやはりクラスに局所化しときたいところ
ちなみにこんなやつ

static const NSString *NETWORK_ERROR_DESCRIPTION = @"cant reach server";
// etc...

static const NSString *NETWORK_ERROR_CODE = 100;
// etc...

// を、1ファイルにずらずら書いて、使う際に毎回
// if(error.code == NETWORK_ERROR_CODE) {
//   //ダイアログ出したり
// } else if (error.code == DB_ERROR_CODE) {
//   //無視したり
// }
// を書かないといけないようなそんなような

何かツッコミ等や改善点あれば教えていただけると助かります

最後に

書いてて思ったのは、アプリごとにこれいちいち書くのはめんどくさいので、ライブラリ作っちゃえばいいじゃん!
と思ったが、時代はSwiftなので、Swiftのエラーハンドリングも調べなければという感じ
というかすでにあるかも?という点は要調査

参考

Dealing with Errors 公式
NSError Class Reference 公式
Objective-C事始め – NSErrorの3つのプロパティ

24
18
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
24
18