Runtime学习 -- Class篇

2016-11-08  本文已影响162人  伯wen
注: 此篇中记录的是以class开头的runtime函数

一、创建对象

创建一个对象

size_t size = class_getInstanceSize([Person class]);
Person *person = class_createInstance([Person class], size);

二、类名、父类、实例变量、成员变量、属性、实例方法、类方法、方法实现

获取指定类的类名 (char *类型字符串)

const char *name = class_getName([Person class])

获取指定类的父类型 (Class类型)

Class class = class_getSuperclass([Person class]);

获取一个指定类型的实例占用内存大小 (size_t 类型)

size_t size = class_getInstanceSize([Person class]);

获取一个类中, 指定名称的实例成员变量的信息

Ivar ivar = class_getInstanceVariable([self class], "_person")

获取属性的信息, 不用打_

objc_property_t property = class_getProperty([self class], "person");

获取对象方法信息 ( "-" 方法)

Method method = class_getInstanceMethod([self class], @selector(methodName));

获取类方法的信息 ( "+" 方法 )

Method method = class_getInstanceMethod([self class], @selector(methodName));

获取方法的具体实现 (IMP)

IMP imp = class_getMethodImplementation([self class], @selector(methodName));

获取方法的具体实现, 返回值类型为struct

IMP imp = class_getMethodImplementation_stret([self class], @selector(methodName));

三、成员变量列表、属性列表、方法列表、协议列表

获取成员变量列表

    unsigned int count;
    Ivar *ivarList = class_copyIvarList([self class], &count);
    for (int i = 0; i < count; i++) {
        Ivar ivar = ivarList[i];
        // 获取成员属性名
        NSString *name = [NSString stringWithUTF8String:ivar_getName(ivar)];
        NSString *type = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
        NSLog(@"%@%@", type, name);
    }

获取属性列表

    unsigned int count;
    objc_property_t *propertyList = class_copyPropertyList([self class], &count);
    for (int i = 0; i < count; i++) {
        objc_property_t property = propertyList[i];
        // 获取成员属性名
        NSString *name = [NSString stringWithUTF8String:property_getName(property)];
        NSString *type = [NSString stringWithUTF8String:property_getAttributes(property)];
        NSLog(@"%@%@", type, name);
    }

获取方法列表

    unsigned int count;
    Method *methodList = class_copyMethodList([self class], &count);
    for (int i = 0; i < count; i++) {
        Method method = methodList[i];
        NSLog(@"%s%s", __func__, sel_getName(method_getName(method)));
    }

获取协议列表

    unsigned int count;
    Protocol *protocolList = class_copyProtocolList(class,&count);
    for (int i = 0; i < count; i++) {
        Protocol *protocol = protocolList[i];
        NSLog(@"%s%s", __func__, [self protocol_getName:protocol]);
    }

四、add: 成员变量、属性、方法、协议

添加成员变量(添加成员变量只能在运行时创建的类,且不能为元类)

    if (class_addIvar([Person class], "country", sizeof(NSString *), 0, "@")) {
      NSLog(@"%sadd ivar success", __func__);
    }else{
      NSLog(@"%sadd ivar fail", __func__);
    }

添加属性

    objc_property_attribute_t type = { "T", "@\"NSString\"" };
    objc_property_attribute_t ownership = { "&", "N" }; // C = copy
    objc_property_attribute_t backingivar  = { "V", "" };
    objc_property_attribute_t attrs[] = { type, ownership, backingivar };

    if (class_addProperty([_person class], "country", attrs, 3)) {
        NSLog(@"%sadd Property success", __func__);
    }else{
        NSLog(@"%sadd Property fail", __func__);
    }

添加方法

    if (class_addMethod([self class], NSSelectorFromString(@"runtimeTestMethod:"), class_getMethodImplementation([self class], NSSelectorFromString(@"runtimeTestMethod:")), "v@:@")) {
        NSLog(@"%sadd method success", __func__);
    }else{
        NSLog(@"%sadd method fail", __func__);
    }

添加协议

    if (class_addProtocol([_person class], @protocol(RuntimeBaseProtocol))) {
        NSLog(@"%sadd protocol success", __func__);
    }else{
        NSLog(@"%sadd protocol fail", __func__);
    }

五、replace: 属性、方法

替换属性的信息(如果没有原属性会新建一个属性)

    objc_property_attribute_t type = { "T", "@\"NSString\"" };
    objc_property_attribute_t ownership = { "C", "" }; // C = copy
    objc_property_attribute_t backingivar  = { "V", "" };
    objc_property_attribute_t attrs[] = { type, ownership, backingivar };

    class_replaceProperty([_person class], "country", attrs, 3);

替代方法的实现

    class_replaceMethod([_person class], @selector(method1), class_getMethodImplementation([_person class], @selector(method2)), "v@:");

六、Class 判断

判断类是否有实现指定方法

    if (class_respondsToSelector([_person class], @selector(methodName))) {
        NSLog(@"%s %@ exist", __func__, NSStringFromClass(class));
    }else{
        NSLog(@"%s %@ non-exist", __func__, NSStringFromClass(class));
    }

查看类是否为元类

    if (class_isMetaClass(class)) {
        NSLog(@"%s %@ isMetaClass", __func__, NSStringFromClass(class));
    }else{
        NSLog(@"%s %@ non-isMetaClass", __func__, NSStringFromClass(class));
    }

查看类是否遵循指定协议

    if (class_conformsToProtocol([Person class], NSProtocolFromString(@"RuntimeBaseProtocol"))) {
        NSLog(@"%s %@ conformsToProtocol %@", __func__, NSStringFromClass(class), NSStringFromProtocol(protocol));
        return YES;
    }else{
        NSLog(@"%s %@ non-conformsToProtocol %@", __func__, NSStringFromClass(class), NSStringFromProtocol(protocol));
        return NO;
    }
上一篇 下一篇

猜你喜欢

热点阅读