NSAssert()

作者: Rumbles | 来源:发表于2017-11-16 15:03 被阅读57次

    一.
    NSAssert()是一个宏,用于开发阶段调试程序中的Bug,通过为NSAssert()传递条件表达式来断定是否属于Bug,满足条件返回真值,程序继续运行,如果返回假值,则抛出异常,并且可以自定义异常描述。
    NSAssert()是这样定义的:

     #define NSAssert(condition, desc)
    

    condition是条件表达式,值为YES或NO;desc为异常描述,通常为NSString。当conditon为YES时程序继续运行,为NO时,则程序异常抛出带有desc描述的异常信息。NSAssert()可以出现在程序的任何一个位置。

    二.
    在ios开发过程中,有时候会用到第三方的静态库(.a文件),OC没有为每个函数(或者方法)定义链接符号,它只为每个类创建链接符号。这样当在一个静态库中使用类别来扩展已有类的时候,链接器不知道如何把类原有的方法和类别中的方法整合起来,就会导致你调用类别中的方法时,会出现selector not recognized的错误,从而导致app闪退。使用这段宏定义他可以虚拟新建一个与名字category 相同.h.m 让编译器 编译通过。即可解决上面的问题。

    写在.m文件

    /**
     Add this macro before each category implementation, so we don't have to use
     -all_load or -force_load to load object files from static libraries that only
     contain categories and no classes.
     More info: http://developer.apple.com/library/mac/#qa/qa2006/qa1490.html .
     *******************************************************************************
    
     Example:
          #import "NSObject+YYAdd.h"
          YYSYNTH_DUMMY_CLASS(NSObject_YYAdd)
     */
    #ifndef YYSYNTH_DUMMY_CLASS
    #define YYSYNTH_DUMMY_CLASS(_name_) \
    @interface YYSYNTH_DUMMY_CLASS_ ## _name_ : NSObject @end \
    @implementation YYSYNTH_DUMMY_CLASS_ ## _name_ @end
    #endif
    

    三.关于block,weak&strong

    /**
     Synthsize a weak or strong reference.
    
     Example:
        @weakify(self)
        [self doSomething^{
            @strongify(self)
            if (!self) return;
            ...
        }];
    
     */
    #ifndef weakify
        #if DEBUG
            #if __has_feature(objc_arc)
            #define weakify(object) autoreleasepool{} __weak __typeof__(object) weak##_##object = object;
            #else
            #define weakify(object) autoreleasepool{} __block __typeof__(object) block##_##object = object;
            #endif
        #else
            #if __has_feature(objc_arc)
            #define weakify(object) try{} @finally{} {} __weak __typeof__(object) weak##_##object = object;
            #else
            #define weakify(object) try{} @finally{} {} __block __typeof__(object) block##_##object = object;
            #endif
        #endif
    #endif
    
    #ifndef strongify
        #if DEBUG
            #if __has_feature(objc_arc)
            #define strongify(object) autoreleasepool{} __typeof__(object) object = weak##_##object;
            #else
            #define strongify(object) autoreleasepool{} __typeof__(object) object = block##_##object;
            #endif
        #else
            #if __has_feature(objc_arc)
            #define strongify(object) try{} @finally{} __typeof__(object) object = weak##_##object;
            #else
            #define strongify(object) try{} @finally{} __typeof__(object) object = block##_##object;
            #endif
        #endif
    #endif
    
    

    四. 实现动态给category 添加属性
    具体参见http://www.jianshu.com/p/4a1531bac39f
    普及一点宏定义 的关键字 一个# 表示要替换变量 ,两个 ##要拼接字符串 ,\表示多行 cmd 是iOS 是一种特定宏 ,表示本地方法, 在这里表示 @selector(_setter:)

    
    /**
     Synthsize a dynamic object property in @implementation scope.
     It allows us to add custom properties to existing classes in categories.
     
     @param association  ASSIGN / RETAIN / COPY / RETAIN_NONATOMIC / COPY_NONATOMIC
     @warning #import <objc/runtime.h>
     *******************************************************************************
     Example:
         @interface NSObject (MyAdd)
         @property (nonatomic, retain) UIColor *myColor;
         @end
         
         #import <objc/runtime.h>
         @implementation NSObject (MyAdd)
         YYSYNTH_DYNAMIC_PROPERTY_OBJECT(myColor, setMyColor, RETAIN, UIColor *)
         @end
     */
    #ifndef YYSYNTH_DYNAMIC_PROPERTY_OBJECT
    #define YYSYNTH_DYNAMIC_PROPERTY_OBJECT(_getter_, _setter_, _association_, _type_) \
    - (void)_setter_ : (_type_)object { \
        [self willChangeValueForKey:@#_getter_]; \
        objc_setAssociatedObject(self, _cmd, object, OBJC_ASSOCIATION_ ## _association_); \
        [self didChangeValueForKey:@#_getter_]; \
    } \
    - (_type_)_getter_ { \
        return objc_getAssociatedObject(self, @selector(_setter_:)); \
    }
    #endif
    
    /**
     Synthsize a dynamic c type property in @implementation scope.
     It allows us to add custom properties to existing classes in categories.
     
     @warning #import <objc/runtime.h>
     *******************************************************************************
     Example:
         @interface NSObject (MyAdd)
         @property (nonatomic, retain) CGPoint myPoint;
         @end
         
         #import <objc/runtime.h>
         @implementation NSObject (MyAdd)
         YYSYNTH_DYNAMIC_PROPERTY_CTYPE(myPoint, setMyPoint, CGPoint)
         @end
     */
    #ifndef YYSYNTH_DYNAMIC_PROPERTY_CTYPE
    #define YYSYNTH_DYNAMIC_PROPERTY_CTYPE(_getter_, _setter_, _type_) \
    - (void)_setter_ : (_type_)object { \
        [self willChangeValueForKey:@#_getter_]; \
        NSValue *value = [NSValue value:&object withObjCType:@encode(_type_)]; \
        objc_setAssociatedObject(self, _cmd, value, OBJC_ASSOCIATION_RETAIN); \
        [self didChangeValueForKey:@#_getter_]; \
    } \
    - (_type_)_getter_ { \
        _type_ cValue = { 0 }; \
        NSValue *value = objc_getAssociatedObject(self, @selector(_setter_:)); \
        [value getValue:&cValue]; \
        return cValue; \
    }
    #endif
    

    不用宏定义的写法

    #import <Foundation/Foundation.h>
    #import <objc/runtime.h>
    
    @interface NSObject (Extension)
    @property (nonatomic, strong) NSArray *books;
    @end
    
    #import "NSObject+Extension.h"
    @implementation NSObject (Extension)
    -(void)setBooks:(NSArray *)books{
        objc_setAssociatedObject(self, @selector(setBooks:), books, OBJC_ASSOCIATION_RETAIN);
    }
    -(NSArray *)books{
        return objc_getAssociatedObject(self, @selector(setBooks:));
    }
    @end
    

    使用:

    #import "NSObject+Extension.h"
    @implementation NSObject (Extension)
    YYSYNTH_DYNAMIC_PROPERTY_OBJECT(books,setBooks,RETAIN, NSArray *);
    @end
    

    五. 写带有返回值的宏定义

    /**
     Convert CFRange to NSRange
     @param range CFRange @return NSRange
     */
    static inline NSRange YYNSRangeFromCFRange(CFRange range) {
        return NSMakeRange(range.location, range.length);
    }
    

    相关文章

      网友评论

        本文标题:NSAssert()

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