美文网首页
Runtime--Method、Ivar、Property篇

Runtime--Method、Ivar、Property篇

作者: Winny_园球 | 来源:发表于2018-04-26 14:13 被阅读0次
    #pragma mark - IBAction
    - (IBAction)logRunTimeAction:(id)sender {
        objc_property_attribute_t attrs[] = { { "T", "@\"NSString\"" }, { "&", "N" }, { "V", "" } };
    
        size_t objSize = class_getInstanceSize([_person class]);
        size_t allocSize = 2 * objSize;
        uintptr_t ptr = (uintptr_t)calloc(allocSize, 1);
    
        // Method
        Method method = [self class_getInstanceMethod:SelfClass selector:@selector(initial:)];
        [self method_getName:method];
        [self method_getImplementation:method]; // 该方法imp_implementationWithBlock使得imp几乎相当于block
        [self method_getTypeEncoding:method];
        [self method_getArgumentType:method];
        [self method_copyReturnType:method];
        [self method_copyArgumentType:method];
        [self method_getReturnType:method];
        [self method_setImplementation:class_getInstanceMethod(SelfClass, @selector(method_setImplementation:))];
        [self method_exchangeImplementations:class_getInstanceMethod([_person class], @selector(runtimeTestAction3)) method:class_getInstanceMethod([_person class], @selector(runtimeTestAction2))];
        [self method_getDescription:method];
    }
    
    #pragma mark - Ivar get
    /**
     *  获取成员变量名
     *
     *  @param ivar 成员变量
     *
     *  @return 变量名
     */
    - (const char *)ivar_getName:(Ivar)ivar {
        return ivar_getName(ivar);
    }
    
    /**
     *  获取成员变量类型编码
     *
     *  @param ivar 成员变量
     *
     *  @return 编码类型
     */
    - (const char *)ivar_getTypeEncoding:(Ivar)ivar {
        return ivar_getTypeEncoding(ivar);
    }
    
    /**
     *  获取成员变量的偏移量
     *
     *  @param ivar 成员变量
     *
     *  @return 偏移量
     */
    - (ptrdiff_t)ivar_getOffset:(Ivar)ivar {
        return ivar_getOffset(ivar);
    }
    
    #pragma mark - Property get
    /**
     *  获取属性名
     *
     *  @param property 属性
     *
     *  @return 属性名
     */
    - (const char *)property_getName:(objc_property_t)property {
        return property_getName(property);
    }
    
    /**
     *  获取属性特性描述字符串
     *
     *  @param property 属性
     *
     *  @return 属性特性字符串
     */
    - (const char *)property_getAttributes:(objc_property_t)property {
        return property_getAttributes(property);
    }
    
    /**
     *  获取属性的特性列表
     *
     *  @param property 属性
     *
     *  @return 特性列表
     */
    - (objc_property_attribute_t *)property_copyAttributeList:(objc_property_t)property {
        unsigned int outCount;
        objc_property_attribute_t *objc_property_attributes = property_copyAttributeList(property,&outCount);
        for (int i = 0; i < outCount; i++) {
            objc_property_attribute_t objc_property_attribute = objc_property_attributes[i];
            NSLog(@"%s %s %s",__func__,objc_property_attribute.name,[self property_copyAttributeValue:property attributeName:objc_property_attribute.name]);
        }
        return objc_property_attributes;
    }
    
    /**
     *  获取属性中指定的特性
     *
     *  @param property      属性
     *  @param attributeName 特性名
     *
     *  @return 特性
     */
    - (const char *)property_copyAttributeValue:(objc_property_t)property attributeName:(const char *)attributeName {
        return property_copyAttributeValue(property,attributeName);
    }
    
    #pragma mark - Method invoke: 方法实现的返回值
    /**
     *  调用指定方法的实现
     *
     *  @param receiver 被调用的对象
     *  @param method   被调用的方法
     */
    - (void)method_invoke:(id)receiver method:(Method)method {
        method_invoke(receiver,method);
    }
    
    #pragma mark - Method get: 方法名;方法实现;参数与返回值相关
    /**
     *  获取方法名
     *
     *  @param method 方法
     *
     *  @return 方法选择器
     */
    - (SEL)method_getName:(Method)method {
        SEL sel = method_getName(method);
        NSLog(@"%s %@",__func__,NSStringFromSelector(sel));
        return sel;
    }
    
    /**
     *  返回方法的实现
     *
     *  @param method 方法
     *
     *  @return 方法的实现
     */
    - (IMP)method_getImplementation:(Method)method {
        IMP imp = method_getImplementation(method);
        return imp;
    }
    
    /**
     *  获取描述方法参数和返回值类型的字符串
     *
     *  @param method 方法
     *
     *  @return 方法的类型字符串
     */
    - (const char *)method_getTypeEncoding:(Method)method {
        const char *methodType = method_getTypeEncoding(method);
        NSLog(@"%s %s",__func__,methodType);
        return methodType;
    }
    
    /**
     *  返回方法的参数的个数
     *
     *  @param method 方法
     *
     *  @return 方法参数的个数
     */
    - (unsigned int)method_getNumberOfArguments:(Method)method {
        unsigned int num  = method_getNumberOfArguments(method);
        // 估计参数数量多出来的2个是调用的对象和selector
        NSLog(@"%s %@ has %d Arguments",__func__,NSStringFromSelector(method_getName(method)),num);
        return num;
    }
    
    #pragma mark - Method copy: 返回值类型,参数类型
    /**
     *  获取指定位置参数的类型字符串
     *
     *  @param method 方法
     */
    - (void)method_getArgumentType:(Method)method {
        unsigned int argumentsCount = [self method_getNumberOfArguments:method];
        char argName[512] = {};
        for (unsigned int j = 0; j < argumentsCount; ++j) {
            method_getArgumentType(method, j, argName, 512);
    
            NSLog(@"%@ 第%u个参数类型为:%s",NSStringFromSelector(method_getName(method)), j, argName);
            memset(argName, '\0', strlen(argName));
        }
    }
    
    /**
     *  获取方法的指定位置参数的类型字符串
     *
     *  @param method 方法
     */
    - (void)method_copyArgumentType:(Method)method {
        unsigned int argumentsCount = [self method_getNumberOfArguments:method];
        for (int i = 0; i < argumentsCount; i++) {
            NSLog(@"%s 第%d个 argument type %s",__func__,i,method_copyArgumentType(method,i));
        }
    }
    
    /**
     *  获取方法的返回值类型的字符串
     *
     *  @param method 方法
     *
     *  @return 返回值类型字符串
     */
    - (char *)method_copyReturnType:(Method)method {
        char *returnType = method_copyReturnType(method);
        NSLog(@"%s return type %s",__func__,returnType);
        return returnType;
    }
    
    /**
     *  通过引用返回方法的返回值类型字符串
     *
     *  @param method 方法
     */
    - (void)method_getReturnType:(Method)method {
        char argNameType[512] = {};
        method_getReturnType(method,argNameType,512);
        NSLog(@"%s return type %s",__func__,argNameType);
    
    }
    
    
    
    #pragma mark - Method set: 方法实现 交换方法实现
    /**
     *  设置方法的实现
     *
     *  @param method 方法
     */
    - (void)method_setImplementation:(Method)method {
        IMP imp = imp_implementationWithBlock(^{
            NSLog(@"%s action",__func__);
        });
        method_setImplementation(method,imp);
    }
    
    /**
     *  交换两个方法的实现
     *
     *  @param method1 方法1
     *  @param method2 方法2
     */
    - (void)method_exchangeImplementations:(Method)method1 method:(Method)method2 {
        method_exchangeImplementations(method1,method2);
        [_person runtimeTestAction2];
        [_person runtimeTestAction3];
    }
    
    
    #pragma mark - Method 方法描述
    - (struct objc_method_description *)method_getDescription:(Method)method {
        struct objc_method_description *description = method_getDescription(method);
        NSLog(@"%s %@",__func__,NSStringFromSelector(description->name));
        return description;

    相关文章

      网友评论

          本文标题:Runtime--Method、Ivar、Property篇

          本文链接:https://www.haomeiwen.com/subject/nunplftx.html