Cocoaには、エラーが起きた時の対処方法として、NSErrorとNSExceptionがあります。
NSErrorとNSExceptionの使い分け
Non-recoverableなケースのみNSExceptionを使い、それ以外は原則としてNSErrorを使います。
NSExceptionを使うケースとしては、methodの引数がinvalidな時(コールバックが必須なのに、nilだったなど)です。引数のチェックに私はよくNSParameterAssertを使っています。
typedef void (^CompletionBlock)(NSArray *array, NSError *error);
- (void)someMethod:(CompletionBlock)callback
{
NSParameterAssert(callback);
// 処理
}
NSErrorの使い方
NSErrorに含まれる情報は大きく3つあります。
- domain
- code
- userInfo
domainは文字列、codeはenumで定義される事が多く、どの領域でエラーが起こったか識別するのに利用します。userInfoはNSDictionaryのインスタンスで、localizedDescriptionというメソッドを呼ぶと、エラーに関する記述が含まれている文字列を返します。この文字列は、エラーが起きた際に、ユーザーに見せる情報としてよく使います。
// objective-c
if (error) {
NSLog(@"%@", [error localizedDescrition]);
}
// swift
if let newError = error {
error.localizedDescription
}
NSErrorの作り方
Cocoaではなく自分のアプリ/ライブラリ由来のNSErrorを定義したい場合は、errorWithDomain:code:userInfo:を使います。
// objective-c
NSString *const ABCErrorDomain = @"com.example.abc";
[NSError errorWithDomain:ABCErrorDomain
code:1
userInfo:nil];
// swift
let ABCErrorDomain = "com.example.abc"
NSError(domain: ABCErrorDomain, code: 1, userInfo: nil)
domainに関しては、リバースドメイン形式が推奨されています。
objective-cで書く場合、専用のheaderファイルとimplementationファイルを用意し、そこにNSErrorに関する定義をまとめます。
// ABCError.h
FOUNDATION_EXPORT NSString *const ABCErrorDomain;
typedef NS_ENUM(int, ABCErrorCode) {
ABCSomeError
};
// ABCError.m
NSString *const WPYErrorDomain = @"com.example.abc";
cf
- http://nshipster.com/nserror/
- https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Exceptions/Exceptions.html
- http://stackoverflow.com/questions/11100951/nsexception-and-nserror-custom-exception-error
- http://stackoverflow.com/questions/8396326/exception-handling-in-entire-application