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

2019-10-27  本文已影响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方法,并没有发现有成员变量
上一篇下一篇

猜你喜欢

热点阅读