美文网首页
iOS开发之断言

iOS开发之断言

作者: brilliance_Liu | 来源:发表于2016-10-31 17:03 被阅读101次

小伙伴们在开发过程,多多少少会接触到各色各样的第三方开源代码。而在这些代码中,我们时长会看见NSAssert,也就是俗称:断言
Foundation中定义了两组断言相关的宏,分别是:

NSAssert / NSCAssert
NSParameterAssert / NSCParameterAssert```
**这两组宏主要在功能和语义上有所差别,这些区别主要有以下两点:**

1.一个不同是介于C和Objective-C之间。NSAssert / NSParameterAssert应该用于Objective-C的上下文(方法)中,而NSCAssert / NSCParameterAssert应该用于C的上下文(函数)中。
2.另一个不同就是如果我们需要确保方法或函数的输入参数的正确性,则应该在方法(函数)的顶部使用NSParameterAssert / NSCParameterAssert;而在其它情况下,使用NSAssert / NSCAssert。**当断言失败时,通常是会抛出一个如下所示的异常:***** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'true is not equal to false'```

Foundation为了处理断言,专门定义了一个NSAssertionHandler来处理断言的失败情况。NSAssertionHandler对象是自动创建的,用于处理失败的断言。当断言失败时,会传递一个字符串给NSAssertionHandler对象来描述失败的原因。**每个线程都有自己的NSAssertionHandler对象。**当调用时,一个断言处理器会打印包含方法和类(或函数)的错误消息,并引发一个NSInternalInconsistencyException异常。就像上面所看到的一样。
我们很少直接去调用NSAssertionHandler的断言处理方法,通常都是自动调用的。

***NSAssertionHandler提供的方法并不多,就三个,如下所示:***
```// 返回与当前线程的NSAssertionHandler对象。
// 如果当前线程没有相关的断言处理器,则该方法会创建一个并指定给当前线程
+ (NSAssertionHandler *)currentHandler
 
// 当NSCAssert或NSCParameterAssert断言失败时,会调用这个方法
- (void)handleFailureInFunction:(NSString *)functionName file:(NSString *)object lineNumber:(NSInteger)fileName description:(NSString *)line, format,...
 
// 当NSAssert或NSParameterAssert断言失败时,会调用这个方法
- (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format, ...

另外,还定义了一个常量字符串,

NSString * const NSAssertionHandlerKey;```
主要是用于在线程的threadDictionary字典中获取或设置断言处理器。
关于断言,还需要注意的一点是在Xcode 4.2以后,在release版本中断言是默认关闭的,这是由宏NS_BLOCK_ASSERTIONS来处理的。也就是说,当编译release版本时,所有的断言调用都是无效的。
我们可以自定义一个继承自NSAssertionHandler的断言处理类,来实现一些我们自己的需求。如Mattt Thompson的[NSAssertionHandler](http://nshipster.com/nsassertionhandler/)实例一样:

@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```
上面说过,每个线程都有自己的断言处理器。我们可以通过为线程的threadDictionary字典中的NSAssertionHandlerKey指定一个新值,来改变线程的断言处理器。如下代码所示:

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  NSAssertionHandler *assertionHandler = [[LoggingAssertionHandler alloc] init];
  [[[NSThread currentThread] threadDictionary] setValue:assertionHandler
                                                 forKey:NSAssertionHandlerKey];
  // ...
 
  return YES;
}```
***
摘自:
[Foundation中的断言处理](http://www.cocoachina.com/ios/20150513/11806.html)

相关文章

  • iOS开发之断言

    小伙伴们在开发过程,多多少少会接触到各色各样的第三方开源代码。而在这些代码中,我们时长会看见NSAssert,也就...

  • iOS开发之定位

    iOS开发之定位 iOS开发之定位

  • NSAssert()使用目的

    转自iOS开发中断言的使用—NSAssert()[https://blog.csdn.net/univcore/a...

  • iOS开发之GCD并发队列

    iOS开发多线程之GCDiOS开发之GCD同步任务加强iOS开发之GCD串行队列iOS开发之GCD并发队列 03 ...

  • iOS开发之NSURLSessionUploadTask上传数据

    iOS开发之NSURLSessionUploadTask上传数据 iOS开发之NSURLSessionUpload...

  • iOS开发多线程之GCD

    iOS开发多线程之GCDiOS开发之GCD同步任务加强iOS开发之GCD串行队列iOS开发之GCD并发队列 GCD...

  • iOS开发之GCD同步任务加强

    iOS开发多线程之GCDiOS开发之GCD同步任务加强iOS开发之GCD串行队列iOS开发之GCD并发队列 004...

  • iOS开发之登录与访客

    iOS开发之登录与访客 iOS开发之登录与访客

  • iOS开发之GCD串行队列

    iOS开发多线程之GCDiOS开发之GCD同步任务加强iOS开发之GCD串行队列iOS开发之GCD并发队列 实例d...

  • 断言

    在iOS开发中,可以使用宏NSAssert()在程序中进行断言处理。NSAssert()使用正确,可以帮助开发者尽...

网友评论

      本文标题:iOS开发之断言

      本文链接:https://www.haomeiwen.com/subject/cleputtx.html