通过前面几篇对Runtime的讲解,本篇汇总一下Runtime实际中常用的一些场景。
1.获取类的基本信息
获取类名:
const char *className = class_getName(class);
获取成员变量:
unsigned int count = 0; Ivar *ivars = class_copyIvarList([GofPerson class], &count); for (int i = 0; i < count; i++) { Ivar ivar = ivars[i]; const char *name = ivar_getName(ivar); NSLog(@"%d.成员变量:%s", i, name); } free(ivars);
获取属性:
unsigned int count = 0; objc_property_t *propertys = class_copyPropertyList([GofPerson class], &count); for (int i = 0; i < count; i++) { objc_property_t property = propertys[i]; const char *name = property_getName(property); const char *attribute = property_getAttributes(property); NSLog(@"%d.propertyName: %s, attribute: %s",i, name, attribute); } free(propertys);
获取类的实例方法:
//获取实例方法列表 unsigned int count = 0; Method *methods = class_copyMethodList(objectClsObj, &count); for (int i = 0; i < count; i++) { Method methodItem = methods[i]; const char *methodType = method_getTypeEncoding(methodItem);// 获取方法参数类型和返回类型 NSLog(@"instance method item%d:%s %s",i, sel_getName(method_getName(methodItem)), methodType); } free(methods);
2.动态创建类和类的基本信息
创建类:
//创建存储空间 Class newClass = objc_allocateClassPair([GofBaseViewController class], "GofClass", 0); /** 动态添加方法 @param cls 类类型 @param name 选择器(SEL) @param imp 函数指针 @param type 方法类型 */ SuppressUndeclaredSelectorWarning(class_addMethod(newClass, @selector(testMetaClass), (IMP)TestMetaClass, "v@:")); //注册这个类 objc_registerClassPair(newClass);
添加成员变量:
class_addIvar(newClass, "name", sizeof(id), log2(sizeof(id)), "@");
添加属性:
//添加属性 objc_property_attribute_t attribute1 = {"T", "@\"NSString\""}; //type objc_property_attribute_t attribute2 = {"C", ""}; //copy objc_property_attribute_t attribute3 = {"N", ""}; //nonatomic objc_property_attribute_t attribute4 = {"V", "_email"}; //variable name objc_property_attribute_t attributesList[] = {attribute1, attribute2, attribute3, attribute4}; if(class_addProperty([GofPerson class], "email", attributesList, 4)) { NSLog(@"add property success!"); } else { NSLog(@"add property failure!"); }
添加方法:
SuppressUndeclaredSelectorWarning(class_addMethod(objectClsObj, @selector(newMethod), (IMP)testNewMethod, "v@:"));
3.关联对象
@interface GofPerson (GofWork) @property (nonatomic, strong) NSString *workSpace; //!<工作空间 @end static const void *s_WorkSpace = "s_WorkSpace"; @implementation GofPerson (GofWork) - (void)setWorkSpace:(NSString *)workSpace { objc_setAssociatedObject(self, s_WorkSpace, workSpace, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (NSString *)workSpace { return objc_getAssociatedObject(self, s_WorkSpace); } @end
4.消息转发/方法交换
详见Runtime之方法。