• 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之方法

  • 相关阅读:
    前端面试1
    关于JavaScript学习,推荐博客及书籍
    GET 和 POST 两种方式来完成Http接口
    mvc Web api 如何在控制器中调用
    c#怎么获取当前页面的url
    MVC3缓存:使用页面缓存
    十大排序算法梳理
    浅谈设计模式——工厂模式
    Java 中的 反射机制
    浅谈设计模式——单例模式
  • 原文地址:https://www.cnblogs.com/LeeGof/p/6696749.html
Copyright © 2020-2023  润新知