您的位置:首页 > 运维架构

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

2016-05-04 11:48 330 查看
本篇主要是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;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息