Foundation中定義了兩組斷言的宏,分別是:
NSAssert / NSCAssert NSParameterAssert / NSCParameterAssert這兩組宏主要在功能和語義上有所差別,這些區(qū)別主要有以下兩點(diǎn):
1、如果我們需要確保方法或函數(shù)的輸入?yún)?shù)的正確性,則應(yīng)該在方法(函數(shù))的頂部使用NSParameterAssert / NSCParameterAssert;而在其它情況下,使用NSAssert / NSCAssert。2、另一個(gè)不同是介于C和Objective-C之間。NSAssert / NSParameterAssert應(yīng)該用于Objective-C的上下文(方法)中,而NSCAssert / NSCParameterAssert應(yīng)該用于C的上下文(函數(shù))中。當(dāng)斷言失敗時(shí),通常是會(huì)拋出一個(gè)如下所示的異常:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'true is not equal to false'Foundation 為了處理斷言,專門定義了一個(gè)NSAssertionHandler來處理斷言的失敗情況。NSAssertionHandler對象是自動(dòng)創(chuàng)建的,用于 處理失敗的斷言。當(dāng)斷言失敗時(shí),會(huì)傳遞一個(gè)字符串給NSAssertionHandler對象來描述失敗的原因。每個(gè)線程都有自己的 NSAssertionHandler對象。當(dāng)調(diào)用時(shí),一個(gè)斷言處理器會(huì)打印包含方法和類(或函數(shù))的錯(cuò)誤消息,并引發(fā)一個(gè) NSInternalInconsistencyException異常。就像上面所看到的一樣。
我們很少直接去調(diào)用NSAssertionHandler的斷言處理方法,通常都是自動(dòng)調(diào)用的。
NSAssertionHandler提供的方法并不多,就三個(gè),如下所示:
①// 返回與當(dāng)前線程的NSAssertionHandler對象。// 如果當(dāng)前線程沒有相關(guān)的斷言處理器,則該方法會(huì)創(chuàng)建一個(gè)并指定給當(dāng)前線程+ (NSAssertionHandler *)currentHandler;②// 當(dāng)NSCAssert或NSCParameterAssert斷言失敗時(shí),會(huì)調(diào)用這個(gè)方法- (void)handleFailureInFunction:(NSString *)functionName file:(NSString *)object lineNumber:(NSInteger)fileName description:(NSString *)line, format,...③// 當(dāng)NSAssert或NSParameterAssert斷言失敗時(shí),會(huì)調(diào)用這個(gè)方法- (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format, ...另外,還定義了一個(gè)常量字符串,主要是用于在線程的threadDictionary字典中獲取或設(shè)置斷言處理器。
NSString * const NSAssertionHandlerKey;我們可以自定義一個(gè)繼承自NSAssertionHandler的斷言處理類,來實(shí)現(xiàn)一些我們自己的需求。如Mattt Thompson的NSAssertionHandler實(shí)例一樣:
@interface LoggingAssertionHandler : NSAssertionHandler@end@implementation LoggingAssertionHandler- (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format, ...{ NSLog(@"NSAssert Failure: Method %@ for object %@ in %@#%i", NSStringFromSelector(selector), object, fileName, line);}- (void)handleFailureInFunction:(NSString *)functionName file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format, ...{ NSLog(@"NSCAssert Failure: Function (%@) in %@#%i", functionName, fileName, line);}@end上面說過,每個(gè)線程都有自己的斷言處理器。我們可以通過為線程的threadDictionary字典中的NSAssertionHandlerKey指定一個(gè)新值,來改變線程的斷言處理器。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. NSAssertionHandler *assertionHandler = [[LoggingAssertionHandler alloc] init]; [[[NSThread currentThread] threadDictionary] setValue:assertionHandler forKey:NSAssertionHandlerKey]; return YES;}新聞熱點(diǎn)
疑難解答
圖片精選