博客> runtime给类添加属性和方法及改变方法
runtime给类添加属性和方法及改变方法
2017-12-13 00:01 评论:0 阅读:431 西单_夜未央
runtime给类添加属性和方法及交换方法

今天在做抽屉效果的时候,遇到一个问题:就是抽屉push出去的子控制器,和其他子控制器混杂了(因为抽屉的自控制pop回来还是抽屉)!于是我就笨笨的想到给UIViewController添加属性:

A :添加动态属性 1.当然是先创建一个UIViewController的分类#import "UIViewController+LMExtension.h"

2.导入牛逼哄哄的#import 就是大家经常念叨的"运行时"

static char const * const fromStrKey = "draw";

@dynamic FromStr;

  • (NSString *)FromStr{

    NSString *str = objc_getAssociatedObject(self, fromStrKey);

    return str; }

  • (void)setFromStr:(NSString *)FromStr{

    [self willChangeValueForKey:@"fromStrKey"];

    objc_setAssociatedObject(self, fromStrKey, FromStr, OBJC_ASSOCIATION_COPY_NONATOMIC);

    [self didChangeValueForKey:@"fromStrKey"];

} 总结:在分类中@property不会生成_变量,也不会实现getter和setter方法,而且分类中不允许定义变量,所以只能用runtime类实现  B4521509-D5BF-420A-92F0-593B8C0C2285.png

玩了rumtime添加属性感觉很不错,于是就去研究了下: B :在运行时动态添加新的函数、修改私有函数、交换其中两个私有函数的实现、替换私有函数...(这才是runtime的牛逼之处)

//这是要添加的方法

  • (int)say:(NSString *)str;

//这是C函数 int sayHallo(id self, SEL _cmd, NSString *str) { NSLog(@"%@", str); return 100;//随便返回个值 }

  • (BOOL)resolveInstanceMethod:(SEL)sel{ class_addMethod([self class], @selector(say:), (IMP)sayHallo, "v@:@"); return [super resolveInstanceMethod:sel]; }

C:交换方法 这里方便起见 新建一个person的类. Method instance_eat = class_getClassMethod(class @selector(resolveInstanceMethod:)); //获取替换后的类方法 Method instance_notEat = class_getClassMethod(self, @selector(LM_resolveInstanceMethod:));

//然后交换类方法 method_exchangeImplementations(instance_eat, instance_notEat);

//获取替换前的类方法 Method class_eat = class_getClassMethod(class, @selector(resolveClassMethod:)); //获取替换后的类方法 Method class_notEat = class_getClassMethod(self, @selector(lm_resolveClassMethod:));

//然后交换类方法 method_exchangeImplementations(class_eat, class_notEat);

void eat_1(id self,SEL sel) { NSLog(@"到底吃不吃饭了"); NSLog(@"%@ %@",self,NSStringFromSelector(sel)); } void eat_2(id self,SEL sel, NSString str1,NSString str2) { NSLog(@"到底吃不吃饭了"); NSLog(@"%@ %@",self,NSStringFromSelector(sel)); NSLog(@"打印两个参数值:%@ and %@",str1,str2); }

+(BOOL)LM_resolveInstanceMethod:(SEL)sel{ //当sel为实现方法中 有 eat 方法 if (sel == NSSelectorFromString(@"eat")) { //就 动态添加eat方法

// 第一个参数:给哪个类添加方法 // 第二个参数:添加方法的方法编号 // 第三个参数:添加方法的函数实现(函数地址) // 第四个参数:函数的类型,(返回值+参数类型) v:void @:对象->self :表示SEL->_cmd class_addMethod(self, sel, (IMP)eat_1, "v@:"); } return YES; } +(BOOL)lm_resolveClassMethod:(SEL)sel{

if (sel == NSSelectorFromString(@"eat:with:")) {

 class_addMethod(objc_getMetaClass("Person"), sel, (IMP)eat_2, "v#:@@");

}

return YES; }

使用  7174404E-F07A-4AA7-B849-1ABB53FDD7C3.jpg

效果  B62C21CA-D07A-48D7-BBC0-C258DC9A19BF.jpg

收藏
0
sina weixin mail 回到顶部