runtime简称为运行时,Object-C 就是这么一种机制,在编译阶段,并不能确定调用哪个函数,只有到运行时才会去找调用哪个函数。在runtime中最重要的要数消息机制了。
这篇文章主要介绍方法交换、动态添加方法、动态添加属性、获取某个类的所有的成员变量。
demo地址在文章结尾
方法交换
因为方法交换只需执行一次,放在类的load方法中进行操作哦
//在load方法中进行方法交换
+ (void)load
{
//获取要调用的方法
Method method1 = class_getInstanceMethod(self, @selector(womanWork));
//获取要换的方法
//获取Man类中的work方法
Method method2 = class_getInstanceMethod([Man class], @selector(work));
//交换
method_exchangeImplementations(method1, method2);
}
动态添加方法
动态添加方法,是在其他类中调用某个类的方法时,后者类中动态加载方法。
//用这个方法来解决动态加载方法
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
//第一个参数:给哪个对象添加方法
//第二个参数:传进来的方法选择器
//第三个参数:要执行的方法实现
//第四个参数:类型:v void @ object : SEL
//传进来的方法无参数
if (sel == @selector(swimming)) {
class_addMethod(self, sel, (IMP)functionName, "v@:");
}
//传进来的方法有参数
if (sel == @selector(swimming:)) {
class_addMethod(self, sel, (IMP)functionName, "v@:@");
}
return [super resolveInstanceMethod:sel];
}
//动态调用这个方法 系统默认添加这两个参数
void functionName(id self,SEL _cmd)
{
NSLog(@"动态添加的方法 没有传入参数的");
}
//有参数的方法
void functionNameWithParam(id self,SEL _cmd,id param)
{
NSLog(@"动态添加方法 有参数的 %@",param);
}
动态添加属性
给一个类动态添加属性 ,在其分类中添加相应的属性,在分类的.m文件中重写get set方法
//分类中添加属性,必须实现这两个方法
//第一个参数:给那个对象添加
- (void)setName:(NSString *)name
{
//第一个参数:给那个对象添加
//第二个参数:添加个什么属性
//第三个参数:属性赋值
//第四个参数:属性的类型
objc_setAssociatedObject(self, @"name", name, OBJC_ASSOCIATION_COPY);
}
- (NSString *)name
{
return objc_getAssociatedObject(self, @"name");
}
获取某个类的所有成员变量
//获取某个类的成员属性
- (IBAction)getIvars:(id)sender {
unsigned int count = 0;
Ivar *ivarList = class_copyIvarList([self class], &count);
for (int i = 0; i < count; i++) {
//取出成员属性
Ivar ivar = ivarList[i];
//取出成员属性名
NSString *propertyName = [NSString stringWithUTF8String:ivar_getName(ivar)] ;
//取出成员属性类型
NSString *propertyType = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)] ;
NSLog(@"%@ %@",propertyName,propertyType);
}
}
网友评论