断言NSAssert的使用

首先要明白“断言”的意思:

知道了“断言”的意思,就明白了为什么“条件表达式”判断为真时,程序就继续,判断为假时,程序就会抛出异常,退出程序了。

NSAssert()的定义是

#define NSAssert(condition, desc)

condition是条件表达式,值为yes或者no,在OC中规定0为假,非0就为真

desc为异常描述,为NSString类型。

当condition为yes时程序继续运行;

当condition为no时程序终止并抛出带有desc描述的异常信息

使用场景: 

使用断言主要是要开发和调试阶段,不是用户交互效果。更多的是开发人员之间的沟通手段,比如你设计了一个类,其中的一个实例变量对于输入的值是有有效限制的。为了防止其他开发人员不合理使用这个类,在类的实现文件中放置多个断言,可以起到一个防错功能。

使用举例:

 NSInteger age = -1;
 
 NSAssert((age > 0 || age == 0), @"年龄不能小于0");

深入了解:

通过制造一个“假”断言,查看日志就会发现,断言NSAssert实际使用的是Foundation框架中的NSAssertionHandler类,用于处理获取假值的断言,而且每个程序线程都拥有其本身的NSAssertionHandler对象,因此,当Foundation框架断言宏的求值为假时,就会将错误情况描述发送给当前线程的NSAssertionHandler对象。该对象会记录错误,并抛出使程序终止的异常(确切地说是一个NSInternallncosistencyException实例)。NSAssertionHandler实例通常不是以编程方式创建的,而是由断言函数创建的。

除了NSAssert断言函数之外,Foundation框架还提供了其他的断言函数:

NSAssert 和 NSCAssert两种“派”别的断言函数有什么区别呢,区别在于 NSAssert 断言宏中含有“self”和“_cmd”,而NSCAssert断言宏中没有用到“self”与“_cmd”:

// NSAssert 断言宏的定义
#if !defined(_NSAssertBody)
#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__ : @"<Unknown 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

VS

// NSCAssert 断言宏的定义
#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__ : @"<Unknown Function>"; 
            NSString *__assert_file__ = [NSString stringWithUTF8String:__FILE__]; 
            __assert_file__ = __assert_file__ ? __assert_file__ : @"<Unknown File>"; 
        [[NSAssertionHandler currentHandler] handleFailureInFunction:__assert_fn__ 
        file:__assert_file__ 
            lineNumber:__LINE__ description:(desc), ##__VA_ARGS__]; 
    }                
        __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS 
    } while(0)
#endif
原文地址:https://www.cnblogs.com/cchHers/p/9013990.html