Runtime之实例总结

通过前面几篇对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之方法

原文地址:https://www.cnblogs.com/LeeGof/p/6696749.html