#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篇
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 前言: 本篇文章将介绍以下几个和 Property 有关的runtime函数的使用:objc_property_t...
- Method Swizzling被称为runtime的黑魔法。swizzle在英文中的本意是“搅和”。 Metho...
- 我原本以为这两个东西没啥好写的,结果是property确实没啥好写的,但是ivar就不少了。 本文不探讨何时该选择...