Runtime方法的使用—Method、Ivar、Property篇

本篇主要是Method、Ivar、Property相关的方法调用

完整代码在这里

#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;

你可能感兴趣的:(ios,method,Runtime,property,Ivar)