美文网首页
iOS 4.NSObject---(分类添加属性) clang

iOS 4.NSObject---(分类添加属性) clang

作者: 龙之天下 | 来源:发表于2019-10-27 17:41 被阅读0次

    1.给NSObject:添加分类,名为:NSObject+object

    2.clang编译OC成C++或者C文件

       #pragma clang assume_nonnull begin
         // @interface NSObject (object)
         // @property (nonatomic,copy) NSString *name;
         /* @end */
      #pragma clang assume_nonnull end
    
      // @implementation NSObject (object)
                //并没有生成如下代码:
                  struct NSObject_IMPL {
                         struct NSObject_IMPL NSObject_IVARS;
                          NSString * _Nonnull _name;//变量
                   }
      // @end
    

    3.分类生成的属性列表变化:

    类生成的属性
    NSString生成属性的格式:{"name","T@"NSString",C,N,V_name"}
    NSInteger生成属性的格式:{"age","Tq,N,V_age"}
    分类生成的属性
    没有setter方法、getter方法 、_name
    NSString生成属性的格式:{"name","T@"NSString",C,N"}
    NSInteger生成属性的格式:{"age","Tq,N"}

    static struct /*_prop_list_t*/ {
    unsigned int entsize;  // sizeof(struct _prop_t)
    unsigned int count_of_properties;
    struct _prop_t prop_list[1];
     } _OBJC_$_PROP_LIST_NSObject_$_object __attribute__ ((used, section ("__DATA,__objc_const"))) = {
           sizeof(_prop_t),
           2,
          {{"name","T@\"NSString\",C,N"},{"age","Tq,N"}}
    };
    
    extern "C" __declspec(dllimport) struct _class_t OBJC_CLASS_$_NSObject;
    
    static struct _category_t _OBJC_$_CATEGORY_NSObject_$_object __attribute__ ((used, section ("__DATA,__objc_const"))) = 
     {
         "NSObject",
         0, // &OBJC_CLASS_$_NSObject,
         0,
         0,
         0,
         (const struct _prop_list_t *)&_OBJC_$_PROP_LIST_NSObject_$_object,
    };
    
    static void OBJC_CATEGORY_SETUP_$_NSObject_$_object(void ) {
         _OBJC_$_CATEGORY_NSObject_$_object.cls = &OBJC_CLASS_$_NSObject;
    }
    
     #pragma section(".objc_inithooks$B", long, read, write)
     __declspec(allocate(".objc_inithooks$B")) static void 
       *OBJC_CATEGORY_SETUP[] = {
          (void *)&OBJC_CATEGORY_SETUP_$_NSObject_$_object,
     };
    
      static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [1] 
      __attribute__((used, section ("__DATA, 
      __objc_catlist,regular,no_dead_strip")))= {
           &_OBJC_$_CATEGORY_NSObject_$_object,
      };
    
     static struct IMAGE_INFO { unsigned version; unsigned flag; } _OBJC_IMAGE_INFO = { 0, 2 };
    

    4.###在NSObject+object.m中添加如下方法

    //添加setter方法
    -(void)setAge:(NSInteger)age{}
    -(void)setName:(NSString *)name{}

     在.m(NSObject (object))生成如下:
          static void _I_NSObject_object_setAge_(NSObject * self, SEL _cmd, NSInteger age) {}
         static void _I_NSObject_object_setName_(NSObject * self, SEL _cmd, NSString * _Nonnull name) {}
    

    运行时:

    1)、分类实例方法列表(_CATEGORY_INSTANCE_METHODS_NSObject_):
          把方法添加到_method_list_t
    
        static struct /*_method_list_t*/ {
           unsigned int entsize;  // sizeof(struct _objc_method)
           unsigned int method_count;
           struct _objc_method method_list[2];
         } _OBJC_$_CATEGORY_INSTANCE_METHODS_NSObject_$_object __attribute__ ((used, section ("__DATA,__objc_const"))) = {
          sizeof(_objc_method),
          2,
          {{(struct objc_selector *)"setAge:", "v24@0:8q16", (void *)_I_NSObject_object_setAge_},
          {(struct objc_selector *)"setName:", "v24@0:8@16", (void *)_I_NSObject_object_setName_}}
     };
    

    2)、_prop_list_t列表(PROP_LIST_NSObject):没有发现变化

    3)、_category_t列表(CATEGORY_NSObject):
    变化:把添加的方法_category_t中

     static struct _category_t _OBJC_$_CATEGORY_NSObject_$_object __attribute__ ((used, section ("__DATA,__objc_const"))) = {
           "NSObject",
           0, // &OBJC_CLASS_$_NSObject,
           (const struct _method_list_t *)&_OBJC_$_CATEGORY_INSTANCE_METHODS_NSObject_$_object,
           0,
           0,
           (const struct _prop_list_t *)&_OBJC_$_PROP_LIST_NSObject_$_object,
    };
    

    4 .简单总结:

          1.不能给分类添加属性name,如果非要给分类添加属性name,需要runtime来关联
          2.即使给分类添加了属性name,XCode没有提示错误,(可以书写),但是编译的时候,既不会生成成员变量,也不会setter和get方法
          3.只是给name添加到属性列表_prop_list_t,但是这个属性并没有V_name
    

    5.关联属性

       通过objc/runtime的方法,进行关联
      static NSString *ageKey  = @"age";
    
       setter : objc_setAssociatedObject(self, &ageKey, [NSNumber numberWithInteger:age], OBJC_ASSOCIATION_ASSIGN);
       getter:objc_getAssociatedObject(self, &ageKey);
      添加关联方法,_prop_list_t不受影响。
       运行之前,我猜想:会自动添加V_name,V_age
       运行后,我的猜想,是错误的:并没有添加
       {{"name","T@\"NSString\",C,N"},
    {"age","Tq,N"}}
    
        简单得出一个结论:
        1.类中,通过@property添加属性,自动生成_name、setName:、 name:           
        2.分类,不能添加属性,需要手动添加。objc_setAssociatedObject实现setter方法,objc_getAssociatedObject实现getter方法,并没有发现有成员变量
    

    相关文章

      网友评论

          本文标题:iOS 4.NSObject---(分类添加属性) clang

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