NSAssert和NSParameterAssert在開發(fā)環(huán)境中經(jīng)常被使用斑响,調(diào)試和驗證代碼參數(shù)的完整性,斷言為真,則表明程序運行正常趣斤,而斷言為假,則意味著它已經(jīng)在代碼中發(fā)現(xiàn)了意料之外的錯誤黎休。Xcode中的斷言在Debug模式默認是開啟的浓领,Realse版本中是禁用的.
基礎斷言
基礎類庫中了兩種斷言,NSAssert和NSParameterAssert是OC斷言势腮,NSCAssert和NSCParameterAssert是C語言斷言联贩。先來看一下NSAssert定義:
The NSAssert macro evaluates the condition and serves as a front end to the assertion handler.
Each thread has its own assertion handler, which is an object of class NSAssertionHandler. When invoked, an assertion handler prints an error message that includes the method and class names (or the function name). It then raises an NSInternalInconsistencyException exception. If condition evaluates to NO, the macro invokes handleFailureInMethod:object:file:lineNumber:description: on the assertion handler for the current thread, passing desc as the description string.
This macro should be used only within Objective-C methods.
Assertions are disabled if the preprocessor macro NS_BLOCK_ASSERTIONS is defined.
**Important:Important**
Do not call functions with side effects in the condition parameter of this macro. The condition parameter is not evaluated when assertions are disabled, so if you call functions with side effects, those functions may never get called when you build the project in a non-debug configuration.
**Note:Note**
Not all release configurations disable assertions by default.
NSParameterAssert的定義:
Assertions evaluate a condition and, if the condition evaluates to false, call the assertion handler for the current thread, passing it a format string and a variable number of arguments. Each thread has its own assertion handler, which is an object of class NSAssertionHandler. When invoked, an assertion handler prints an error message that includes method and class names (or the function name). It then raises an NSInternalInconsistencyException exception.
This macro validates a parameter for an Objective-C method. Simply provide the parameter as the condition argument. The macro evaluates the parameter and, if it is false, it logs an error message that includes the parameter and then raises an exception.
Assertions are disabled if the preprocessor macro NS_BLOCK_ASSERTIONS is defined. All assertion macros return void.
**Important:Important**
Do not call functions with side effects in the condition parameter of this macro. The condition parameter is not evaluated when assertions are disabled, so if you call functions with side effects, those functions may never get called when you build the project in a non-debug configuration.
**Note:Note**
Not all release configurations disable assertions by default.
兩者的定義類似,大概意思就是如果是false就會調(diào)用當前線程Assertion Hanlder進行處理捎拯,非Debug模式下可能所有的斷言都不會調(diào)用泪幌,最后一句很重要,并不是所有的發(fā)布配置會禁用斷言署照,如果想看斷言是否禁用祸泪,需要看一下設置:
簡單測試:
NSString *result=@"中山郎";
NSInteger count=10;
NSAssert(count>10, @"總數(shù)必須大于10");
NSLog(@"斷言執(zhí)行之后");
NSParameterAssert(nil);
NSParameterAssert(![result isEqualToString:@"FlyElephant"]);
NSLog(@"Name:%@",result);
NSParameterAssert([result isEqualToString:@"FlyElephant"]);
崩潰信息:
** FECategory[23811:248235] *** Assertion failure in -[ViewController setupAssert], /ViewController.m:45**
** FECategory[23811:248235] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '****總數(shù)必須大于****10'**
NSAssertionHandler
NSAssert異常處理的時候默認是NSAssertionHandler處理的,不過我們可以自定自己的Handler建芙,實現(xiàn)兩個方法:
- (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(nullable NSString *)format,... NS_FORMAT_FUNCTION(5,6);
- (void)handleFailureInFunction:(NSString *)functionName file:(NSString *)fileName lineNumber:(NSInteger)line description:(nullable NSString *)format,... NS_FORMAT_FUNCTION(4,5);
handleFailureInMethod處理OC方法中的斷言没隘,handleFailureInFunction處理C函數(shù)中的斷言
自定義繼承自NSAssertionHandler的類FEAssertionHandler:
@implementation FEAssertionHandler
-(void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format, ...{
NSLog(@"FlyElephant-FEAssertionHandler: Method %@ for object %@ in %@--line:%li", NSStringFromSelector(selector), object, fileName, (long)line);
}
-(void)handleFailureInFunction:(NSString *)functionName file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format, ...{
NSLog(@"FlyElephant-FEAssertionHandler:Function (%@) in %@--line:%li", functionName, fileName, (long)line);
}
@end
AppDelegate中設置斷言處理:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
FEAssertionHandler *hanlder = [[FEAssertionHandler alloc] init];
[[[NSThread currentThread] threadDictionary] setValue:hanlder forKey:NSAssertionHandlerKey];
return YES;
}