• Runtime


    Runtime


    首先需要导入<objc/runtime.h>
    一、Class
    获取类的成员变量
    Ivar *class_copyIvarList(Class cls,int *outCount);

     unsigned int count;
    Ivar *ivars = class_copyIvarList([self class], &count);
    // 对变量进行操作
    // 使用完成之后要释放ivars
    free(ivars);

    获取实例方法
    Method class_getInstanceMethod(Class cls, SEL name)

            Class originCls = [p class];
    Class curCls = [self class];

    SEL originSel = @selector(scold:);
    SEL curSel = @selector(myScold:);

    Method originM = class_getInstanceMethod(originCls,originSel);
    Method curM = class_getInstanceMethod(curCls, curSel);

    获取类方法
    Method class_getClassMethod(Class cls, SEL name)

    获取IMP(类的实现)

    IMP class_getMethodImplementation(Class cls, SEL name)

    获取全部实例方法
    Method *class_copyMethodList(Class cls, unsigned int *outCount)

    获取类所遵守的所有协议

    Protocol * __unsafe_unretained *class_copyProtocolList(Class cls, unsigned int *outCount)

    获取类所有属性
    objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount)

     unsigned int count;
    // Ivar *ivars = class_copyIvarList([object class], &count);

    objc_property_t *properties = class_copyPropertyList([object class], &count);

    动态增加方法
    BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)

    BOOL ok = class_addMethod(originCls, curSel, (IMP)method_getImplementation(curM), method_getTypeEncoding(curM));
       - (void)addMethod{
    JKPerson *p = [[JKPerson alloc] init];

    // 动态增加方法
    class_addMethod([p class], @selector(eat), (IMP)eat, "v@:");
    // IMP 是eat函数的指针
    // "v@:@",v代表void,无返回值,若返回值为int,则为i;
    // @代表 id sel; : 代表 SEL _cmd;
    // “v@:@@” 意思是,两个参数的没有返回值。
    // 一个Objective-C方法是一个简单的C函数,
    // 它至少包含两个参数—self和_cmd。
    // 所以,我们的实现函数(IMP参数指向的函数)至少需要两个参数

    // 调用新增加的方法
    [p performSelector:@selector(eat)];
    }

    void eat(id self, SEL _cmd){
    printf("新来的 ");
    }

    替换两个方法

    IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types)

    交换两个方法
    void method_exchangeImplementations(Method m1, Method m2)

    if (ok) {
    class_replaceMethod(originCls, originSel, (IMP)method_getImplementation(curM), method_getTypeEncoding(curM));
    class_replaceMethod(originCls, curSel, (IMP)method_getImplementation(originM), method_getTypeEncoding(originM));
    }else{
    method_exchangeImplementations(originM, curM);
    }

    添加实例变量

    class_addIvar(Class cls, const char *name, size_t size, uint8_t alignment, const char *types)

    class_addIvar([p class], "sex", sizeof(NSString *), 0, "@");

    二、object

    获取对象类型

    const char *object_getClassName(id obj)

    获取实例变量
    id object_getIvar(id obj, Ivar ivar)

    给变量赋值
    void object_setIvar(id obj, Ivar ivar, id value)

    object_setIvar(p, class_getInstanceVariable([p class], "sex"), @"m");
    NSString *sex = object_getIvar(p, class_getInstanceVariable([p class], "sex"));

    三、Ivar
    获取变量名
    const char *ivar_getName(Ivar v)

    获取变量类型等信息

    const char *ivar_getTypeEncoding(Ivar v)

    四、property(objc_property_t)
    获取属性名
    const char *property_getName(objc_property_t property)

    获取属性类型、值等相关信息

    const char *property_getAttributes(objc_property_t property)

     // 属性名称
    NSString *propertyName = [NSString stringWithUTF8String:property_getName(property)];

    NSString *propertyAttribute = [NSString stringWithUTF8String:property_getAttributes(property)]; // T@"NSString",C,N,V_name
    // 解析属性类型
    NSString *tmpType = [[propertyAttribute componentsSeparatedByString:@","] firstObject];
    NSInteger len = tmpType.length;
    NSString *propertyType = [tmpType substringWithRange:NSMakeRange(3, len - 4)];

     
  • 相关阅读:
    第一周(LNMP-Nginx_php-fpm-80转443)
    mysql编译安装
    PB中的DataStore的应用示例
    linux 安装 rabbitmq
    php 扩展 rabbitmq popt
    mongodb基本指令
    单点登录
    js调用打印机打印
    nginx开启tls1.2及一些注意问题
    蓝桥杯2017年省赛A组题目总结
  • 原文地址:https://www.cnblogs.com/buakaw/p/5725689.html
Copyright © 2020-2023  润新知