IOSのアサーション(NSAssert)アプリケーション



Assertion Application Ios



NSAssert()は、開発段階でバグをデバッグするために使用されるマクロです。 NSAssert()の条件式を渡してバグかどうかを判断することにより、条件はtrueを返し、プログラムは実行を継続し、false値が返された場合はスローされます。例外、および例外の説明はカスタマイズできます。

ソースコードを見ると、NSAssertがそのように定義されていることがわかります。NSAssert(条件、説明)、条件は反対の値を取ります。たとえば、値をnullにできない場合、NSAssert(param!= nil、@ 'paramは空にすることはできません')



#define NSAssert(condition, desc, ...) do { __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS if (__builtin_expect(!(condition), 0)) { NSString *__assert_file__ = [NSString stringWithUTF8String:__FILE__] __assert_file__ = __assert_file__ ? __assert_file__ : @'' [[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd object:self file:__assert_file__ lineNumber:__LINE__ description:(desc), ##__VA_ARGS__] } __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS } while(0) #endif #if !defined(_NSCAssertBody) #define NSCAssert(condition, desc, ...) do { __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS if (__builtin_expect(!(condition), 0)) { NSString *__assert_fn__ = [NSString stringWithUTF8String:__PRETTY_FUNCTION__] __assert_fn__ = __assert_fn__ ? __assert_fn__ : @'' NSString *__assert_file__ = [NSString stringWithUTF8String:__FILE__] __assert_file__ = __assert_file__ ? __assert_file__ : @'' [[NSAssertionHandler currentHandler] handleFailureInFunction:__assert_fn__ file:__assert_file__ lineNumber:__LINE__ description:(desc), ##__VA_ARGS__] } __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS } while(0) #endif

NSAssertとassertの違い

NSAssertとassertはどちらもアサーションです。主な違いは、assertは、アサーションが失敗したときにプログラムを終了するだけであり、NSAssertはエラーメッセージを報告して出力することです。したがって、NSAssertを使用するだけで、assertを使用することはできません。

NSAssert / NSCAssert

iOSで最もよく使用されるのは、NSAssert / NSCAssertとNSParameterAssert / NSCparameterAssertの2組のアサーションです。違いを知るために、それらの定義(上記)を見てみましょう。



定義からわかるように、前者はObjectCに適したメソッドであり、_cmdとselfはランタイムに関連しています。後者はCの関数です。
NSParameterAssert / NSCparameterAssert 2つの違いは、Objective-Cの前者の方法でもあり、C関数の後者の方法でもあります。
実際の開発では、前者を使用することができます。

NSAssert / NSCAssertとNSParameterAssert / NSCparameterAssertの違いは、前者は条件付きアサーション用であり、後者はパラメーターが存在するかどうかに関するアサーション専用であるということです。デバッグ時には、それらを組み合わせて、最初にパラメーターを決定し、次に理由をさらに主張することができます。

NSAssertの使用法

int a = 1 NSCAssert(a == 2, @'a must equal to 2') //The first argument is a condition. If the first argument does not satisfy the condition, the following string will be logged and printed.

実行がクラッシュし、次のようにコンソールに情報が出力されます。



*** Assertion failure in *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'a must equal to 2'

NSParameterAssertの使用法

- (void)assertWithPara:(NSString *)str { NSParameterAssert(str) // Only one parameter is needed. If the parameter exists, the program continues to run. If the parameter is empty, the program stops printing the log. //further code ... }

メソッドがassertWithParaと呼ばれる場合:着信パラメーターが空の場合、次のログ

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: str'

ログの数値は、コードの何行が間違っているかを示しています。

Xcodeはデフォルトでリリース環境でアサーションをキャンセルし、アサーションを閉じるのを忘れることによって引き起こされるプログラムの不安定性を排除しました。したがって、開発中に大胆に使用することを心配する必要はありません。

カスタムNSAssertionHandler

NSAssertionHandlerインスタンスは、エラーアサーションを処理するために自動的に作成されます。 NSAssertおよびNSCAssert条件がエラーとして評価された場合、エラーを示す文字列がNSAssertionHandlerインスタンスに送信されます。各スレッドには、独自のNSAssertionHandlerインスタンスがあります。
アサーションが使用されたときにコンソールがエラーを出力するように処理方法をカスタマイズできますが、プログラムは直接クラッシュしません。

#import 'MyAssertHandler.h' @implementation MyAssertHandler / / Handle Objective-C assertions -(void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format, ... { NSLog(@'NSAssert Failure: Method %@ for object %@ in %@#%li', NSStringFromSelector(selector), object, fileName, (long)line) } / / Handling C language assertions -(void)handleFailureInFunction:(NSString *)functionName file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format, ... { NSLog(@'NSCAssert Failure: Function (%@) in %@#%li', functionName, fileName, (long)line) } @end

スレッドに処理クラスを追加します

NSAssertionHandler *myHandler = [[MyAssertHandler alloc] init] / / to the current thread processing class [[[NSThread currentThread] threadDictionary] setValue:myHandler forKey:NSAssertionHandlerKey]