- runtime api 介绍
- 玩一下常用的api
- objc_系列函数关注于宏观使用,如类于协议的空间分配,注册,注销等操作
- class_系列函数关注于类的内部,如实例变量,属性,方法,协议等相关问题
- object_系列函数关注于对象的角度,如实例变量
- method_系列函数关注于方法内部,如方法的参数及返回值类型和方法的实现
- property_系列函数关注于属性的内部,如属性的特性等
- protocol_系列函数关注于协议相关
- ivar_xxx函数关注于实例变量相关
- sel_xxx主要讨论关于方法编号相关的东西
- imp_xxx主要讨论关于方法实现相关
玩一下常用的api
// 创建类
Class SPCat = objc_allocateClassPair([NSObject class], "SPCat", 0);
// 添加实例变量
NSString *name = @"lzy";
class_addIvar(SPCat, name.UTF8String, sizeof(id), log2(sizeof(id)), @encode(id));
// 添加方法
class_addMethod(SPCat, @selector(hunting), (IMP)hunting, "v@:");
// 注册类
objc_registerClassPair(SPCat);
NSLog(@"%@", SPCat);
// 创建实例对象
id cat = [[SPCat alloc] init];
[cat setValue:@"Tom" forKey:@"name"];
NSLog(@"name = %@", [cat valueForKey:@"name"]);
// 方法调用
[cat performSelector:@selector(hunting)];
// 交换方法
Method method1 = class_getMethodImplementation(self, @selector(viewWillAppear:));
Method method2 = class_getInstanceMethod(self, @selector(sp_viewWillAppear:));
-----------------------------
// 关联属性
- (void)setViewColor:(NSString *)viewColor {
objc_setAssociatedObject(self, &associatedObjectKey, @"addProperty", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSString *)viewColor {
return objc_getAssociatedObject(self, &associatedObjectKey);
}
// 获取成员变量列表
- (void)encodeWithCoder:(NSCoder *)coder {
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([self class], &count);
for (int i = 0; i < count; i++) {
Ivar var = ivars[i];
const char *name = ivar_getName(var);
NSString *key = [NSString stringWithUTF8String:name];
id value = [self valueForKey:key];
[coder encodeObject:value forKey:key];
}
}
说明:本篇转载自简书作者Cooci_和谐学习_不急不躁的文章iOS底层原理(二):Runtime研究(二)