美文网首页iOS性能优化程序员iOS开发进阶
浅析YYKit(base 篇)之头文件解析 1

浅析YYKit(base 篇)之头文件解析 1

作者: 嘿晴天 | 来源:发表于2015-12-18 20:23 被阅读1310次

    yykit 是最近一个很火的开源框架,今天来研究看看yykit源码和一些原理,刚拿到yykit还是 很惊讶,来看看yykit 的目录,功能不仅强大,而且是十分全面的,我们来看看他的目录结构


    EA102D35-DD95-4EFA-8098-325B855E8CE7.png

    不得不惊叹,真的好全面,一篇文章根本看不完,今天还是先从base 说起吧,

    09ECF4C2-6F37-40F8-BCBB-EEAD1AE9C19F.png

    展开base 也是不少东西,先来看看这个头文件定义了什么吊炸天的东西
    一开始看就尼玛就卡主了,

    #ifdef __cplusplus
    #define YY_EXTERN_C_BEGIN  extern "C" {
    #define YY_EXTERN_C_END  }
    #else
    #define YY_EXTERN_C_BEGIN
    #define YY_EXTERN_C_END
    #endif
    

    这是什么鬼啊,各种百度,google之后总算是有些眉目了
    先看 #ifdef __cplusplus google 之后发现 c++中定义了__cplusplus,C语言中没有该定义。即这个是用来:识别是c代码还是c++代码
    在看EXTERN_C ,调用extern "C"会让c++编译器按照c的编译格式来编译。多用于c++库的头文件。 也即是说这个在c++的环境下,会强制编译器用 C 语言的规则去编译,而不是用 C++ 语言的规则。。因为 C++ 为了实现函数重载会把函数名和参数等联合起来合成一个中介的函数名,如果 C 函数也被这样编译会出问题,所以在我看来这个是为了兼容c++环境不会编译报错。
    好吧解决了这个 在往下看看有什么比较难理解的东西
    接下来是一个两重判断的 宏定义

    #ifndef YY_CLAMP // return the clamped value
    #define YY_CLAMP(_x_, _low_, _high_)  (((_x_) > (_high_)) ? (_high_) : (((_x_) < (_low_)) ? (_low_) : (_x_)))
    #endif
    

    咋一看不知道有什么用写成if else 语句大概是

        if(x>high)
            return high;
        else
        {
            if(x<low)
                return  low;
            else
                return  x;
        }
    

    好吧接下来往下看吧

    #ifndef YY_SWAP // swap two value
    #define YY_SWAP(_a_, _b_)  do { __typeof__(_a_) _tmp_ = (_a_); (_a_) = (_b_); (_b_) = _tmp_; } while (0)
    #endif
    

    虽然这个一眼就看出来是个交换 函数还是有两个地方需要注意的为什么要用这个关键字呢typeof 还有为什么要用do while 直接用if else 不是就行了吗
    百度一下你就知道
    typeof(var) 是gcc对C语言的一个扩展保留字,用于声明变量类型,var可以是数据类型(int, char*..),也可以是变量表达式。也即是说 变量a 还可以是个变量表达式这里吊吊的
    ,但为啥要用do while 这里就请众大神指点迷津了。

    就不一一解析,看一些比较特别的吧

    #ifndef YYSYNTH_DUMMY_CLASS
    #define YYSYNTH_DUMMY_CLASS(_name_) \
    @interface YYSYNTH_DUMMY_CLASS_ ## _name_ : NSObject @end \
    @implementation YYSYNTH_DUMMY_CLASS_ ## _name_ @end
    #endif
    

    这一段还是挺特别的, 但oc 编译静态库 要在build setting other linker flag设置 -all_load 和-Objc才可以将category 编进去
    使用这段宏定义他可以虚拟新建一个与名字category 相同.h.m 让编译器 编译通过
    但是每次要对所有category 都要申明这个的话可能会比较麻烦,直接加-all_load 据官方文档说,它可以使生成的可执行文件较大,并且产生一些不需要的文件

    #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
    //调用的方法
      @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
    
    

    使用runtime 运行时属性 给catetory 动态添加属性

    相关文章

      网友评论

      • 小凡凡520:很牛逼的酱紫
      • 横渡:不好意思,我说了句废话。
      • 横渡:extern "C"是为了编译器编译这段代码时以C语言的方式编译,而非C++的方式
        嘿晴天:@哈你 好的,原来如此
      • Pr_Chen:do-while应该是为了防止出现在 if(条件) YY_SWAP(_a_, _b_); 时执行语句没有加大括号的问题,但是大括号后面是不能加分号的,所以就用do-while吃掉那个分号.有篇文章http://onevcat.com/2014/01/black-magic-in-macro/ .不知这样的解释对不对.
        luochuanAD:@Pr_Chen 文章真长,学到了很多.
      • ziyouzhe4:您好,我测试了一下这个:YYSYNTH_DUMMY_CLASS() 加上 _name_和name 有啥区别吗? :grin: 我也是刚刚看这些,很多不懂的地方,
        ziyouzhe4:@嘿晴天 哦哦,谢谢回复,学习中
        嘿晴天:@ma_jack 加name也可以的,他只是一个参数

      本文标题:浅析YYKit(base 篇)之头文件解析 1

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