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方法,并没有发现有成员变量