运行时机制
isa、属性列表、方法列表、协议列表
isa
isa指针是什么?
instance的isa指针指向class(类对象)
当调用对象方法时候,通过instance的isa指针,找到类对象,最后找到对象方法完成调用。
class的isa指向meta-class
当调用类方法时候,通过class的isa指针,找到元类对象,最后找到元类的类方法完成调用。
superClass指针
当Student的instance对象调用Person的对象方法时,先是通过Student的实例对象的isa指针找到它的类对象,再通过superClass指针找到Person的类对象,最后找到对象方法完成调用。
Meta-Class指针
当Student的class要调用Person的类方法时,先通过isa指针找到Student的meta-class,然后通过superClass找到Person的meta-class,最后找到类方法完成调用。
isa、superClass 总结
- instance的isa指向class
- class的isa指向meta-class
- meta-class的isa指向基类的meta-class
- class的superclass指向父类的class
- meta-class的superClass指向父类的meta-class
- 基类的meta-class的superClass指向基类的class
属性列表
此处指运行时获取属性列表以及对应的属性操作
property_getAttributes主要用于获取一个类的property即该property的属性数据,也叫metadata(元数据),涉及到得运行时函数包括class_copyPropertyList,property_getName和propert_getAttributes
举个例子
@interface RtTest : NSObject
@property (nonatomic, assign) int sidNum;
@end
@implementation RtTest
@end
u_int count = 0;
objc_property_t *propertys = class_copyPropertyList([self class], &count);
NSMutableArray *arr = [NSMutableArray arrayWithCapacity:0];
for (int i=0; i<count; i++) {
//获取的是c语言字符串
const char *propertyName = property_getName(propertys[i]);
//转成oc的NSString
NSString *temName = [NSString stringWithUTF8String:propertyName];
[arr addObject:temName];
}
//由于class_copyPropertyList底层是C语言,所以需要手动释放
free(propertys);
NSLog(@"属性列表%@",arr);
解析:其中T是类型i 代表int;V是名字接着sidNum,N非原子性nonatomic
结论:
1.property_getName意如其名
2.property_getAttributes,其作用就是用来获取属性的真实类型。
NSString *const TypeInt = @"i"; 整数类型
NSString *const TypeShort = @"s"; 双字节类型
NSString *const TypeFloat = @"f"; float 浮点型
NSString *const TypeDouble = @"d"; double 双精度浮点型
NSString *const TypeLong = @"l"; long 长整型
NSString *const TypeLongLong = @"q";
NSString *const TypeChar = @"c"; char 单字节类型
NSString *const TypeBOOL1 = @"c"; bool 类型
NSString *const TypeBOOL2 = @"b"; bool 类型
NSString const TypePointer = @""; 指针类型
NSString *const TypeIvar = @"^{objc_ivar=}";
NSString *const TypeMethod = @"^{objc_method=}"; oc 方法类型
NSString *const TypeBlock = @"@?"; oc 闭包类型
NSString *const TypeClass = @"#"; oc class 类类型
NSString *const TypeSEL = @":"; oc slector 触发器方法类型
NSString *const TypeId = @"@"; oc 泛型id类型
补充 class_copyIvarList
//class_copyIvarList不仅可以获取@property声明的变量,还可以获取{}中声明的变量
u_int count = 0;
Ivar *propertys = class_copyIvarList([self class], &count);
NSMutableArray *arr = [NSMutableArray arrayWithCapacity:0];
for (int i=0; i<count; i++) {
//获取的是c语言字符串
Ivar ivar = propertys[i];
NSString *ivarName = [NSString stringWithUTF8String:ivar_getName(ivar)];
[arr addObject:ivarName];
}
//由于class_copyPropertyList底层是C语言,所以需要手动释放
free(propertys);
NSLog(@"属性列表1%@",arr);
方法列表
Method *methodList = class_copyMethodList([RtTest class], &count);
NSMutableArray *arr = [NSMutableArray array];
for (unsigned int i = 0; i < count; i++) {
Method method = list[i];
const char *name = sel_getName(method_getName(method));
NSString *ocName = [NSString stringWithUTF8String:name];
[arr addObject:ocName];
}
//由于class_copyMethodList底层是C语言,所以需要手动释放
free(methodList);
NSLog(@"方法列表%@",arr);