整体结构
objc_class
|_ Class isa
|_ NSObject
objc_class 的结构
Class super_class OBJC2_UNAVAILABLE;
const char *name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
struct objc_cache *cache OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
super_class 父类
name 类名称
ivars 属性列表
methodLists 方法列表
protocols 协议列表
基础概念:
IMP 指向定义方法起始的指针
id (*IMP)(id, SEL, ...)
第一个参数指向的是self,第二个参数指向方法选择器,后面是其他方法的参数
SEL 方法选择器
选择器由编译器生成,在类加载之后通过runtime自动生成
Method 类中定义的方法
Ivar 成员变量
property = Ivar + setter + getter
各种方法:
1.获取成员变量
Ivar sonProperty = class_getInstanceVariable(sonClass, "teacher");
NSString *teaher = object_getIvar(son, sonProperty);
2.获取成员变量列表
id sonClass = objc_getClass("Son");
unsigned int outCount;
Ivar *sonProperties = class_copyIvarList(sonClass, &outCount);
for (int i = 0; i < outCount; i++) {
Ivar tempProperty = sonProperties[i];
NSString *ivarName = [NSString stringWithUTF8String:ivar_getName(tempProperty)];
NSString *ivarContent = object_getIvar(son, tempProperty);
NSLog(@"propertyName -> %@ property content -> %@", ivarName, ivarContent);
}
free(sonProperties);
3.获取属性列表
id sonClass = objc_getClass("Son");
unsigned int outCount;
objc_property_t *propertyList = class_copyPropertyList(sonClass, &outCount);
for (int i = 0; i < outCount; i++) {
objc_property_t property = propertyList[i];
NSString *propertyName = [NSString stringWithUTF8String:property_getName(property)];
NSString *propertyAttributes = [NSString stringWithUTF8String:property_getAttributes(property)];
NSLog(@"propertyName -> %@ propertyAttributes -> %@", propertyName, propertyAttributes);
}
free(propertyList);
// console output:
// propertyName -> bikeName propertyAttributes -> T@"NSString",C,N,V_bikeName
属性类型字符串
编码 | 与property相对应的 |
---|---|
R | readonly |
C | copy |
& | retain |
N | nonatomic |
GsampleName | getter=sampleName |
SsampleName | setter=sanpleName |
D | dynamic |
W | __weak |
4.添加property方法
此方法仅能够添加property,但还缺少对应的ivar,getter,setter。attributes中添加的是属性类型字符串。
id carClass = objc_getClass("Car");
@autoreleasepool {
objc_property_attribute_t type = { "T", [[NSString stringWithFormat:@"@\"%@\"",NSStringFromClass([NSString class])] UTF8String] }; //type
objc_property_attribute_t ownership0 = { "C", "" }; // C = copy
objc_property_attribute_t ownership = { "N", "" }; //N = nonatomic
objc_property_attribute_t backingivar = { "V", [[NSString stringWithFormat:@"_%@", @"speed"] UTF8String] }; //variable name
objc_property_attribute_t attrs[] = { type, ownership0, ownership, backingivar };
BOOL isSuccess = class_addProperty(carClass, "speed", attrs, 4);
NSLog(@"is success -> %d",isSuccess);
// console output:
// is success -> 1
}
5.添加成员变量方法
class_addIvar方法不能向已有的类添加成员变量,并且类不能是metaclass。
Class cls = objc_allocateClassPair(Car.class, "CarSubClass", 0); //创建Car类的子类
BOOL isAddSuccess = class_addIvar(cls, "speed", sizeof(NSString *), log2(_Alignof(NSString *)), @encode(NSString)); //添加成员变量
objc_registerClassPair(cls);
if (isAddSuccess) {
id accord = [[cls alloc] init];
Ivar speed = class_getInstanceVariable(cls, "speed");
object_setIvar(accord, speed, @"120");
NSString *accordSpeed = object_getIvar(accord, speed);
NSLog(@"accord speed -> %@",accordSpeed);
// console output:
// accord speed -> 120
}
参考代码 github链接