NSAssert 断言

NSAssert 是c语言的一个宏定义。 看一下具体定义:

#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)
具体使用:

NSAssert(condition, desc);

当condition为空的时候,中断程序,打印后面的desc。
所以一般condition一般放的是一个对象或者 对象 != nil。后面的desc一般放字符串。
注意condition不支持逻辑或语法

//错误写法
NSAssert(a != nil || b != nil,  @"dddd");
NSAssert、assert和NSParameterAssert的区别:

assert 和 NSParameterAssert都只有一个参数,即condition,不会有后面的错误描述。

从 Xcode 4.2 开始,发布构建默认关闭了断言,它是通过定义 NS_BLOCK_ASSERTIONS 宏实现的。也就是说,当编译发布版时,任何调用 NSAssert 等的地方都被有效的移除了。

自定义NSAssertionHandler

NSAssertionHandler实例是当前线程自动创建的,用于处理错误断言。当使用NSAssert发生错误的时候的时候会向NSAssertionHandler发送错误的字符串。我们可以通过自定义NSAssertionHandler重写处理方法,从而避免程序崩溃。

@implementation CustomAssertHandler
//处理Objective-C的断言
- (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);
}

同时需要在线程中将自定义的NSAssertionHandler替换。

//自己定义的NSAssertionHandler
    NSAssertionHandler *myHandler = [[CustomAssertHandler alloc] init];
    //给当前的线程
    [[[NSThread currentThread] threadDictionary] setValue:myHandler forKey:NSAssertionHandlerKey];

到这,当NSAssert检测当为空的对象时,就会调用handleFailureInMethod,此时程序不会崩溃。

你可能感兴趣的:(NSAssert 断言)