iOS runtime基本用法
本內(nèi)容為作者原創(chuàng), 未經(jīng)允許, 不得用于商業(yè)用途
一. 改變實(shí)例變量的值 (KVC/MJExtension都是通過這種方式來實(shí)現(xiàn)的)
-
添加Person類, 只添加了name屬性, 這里跳過實(shí)現(xiàn)文件
@interface Person : NSObject @property (copy, nonatomic) NSString *name; @end
-
創(chuàng)建Person類型的實(shí)例對(duì)象
self.person = [Person new]; self.person.name = @"homer"; NSLog(@"%@", self.person.name);
-
添加方法, 修改name屬性的值
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { /// 獲取變量個(gè)數(shù) unsigned int count = 0; /// 獲取所有的實(shí)例變量 Ivar *ivar = class_copyIvarList([self.person class], &count); /// 遍歷 for (int i = 0; i < count; i++) { /// 實(shí)例變量 Ivar var = ivar[i]; /// 實(shí)例變量名字 const char *varName = ivar_getName(var); /// 轉(zhuǎn)化一下 NSString *name = [NSString stringWithUTF8String:varName]; if ([name isEqualToString:@"_name"]) { object_setIvar(self.person, var, @"lynn"); break; } } NSLog(@"%@", self.person.name); }
-
控制臺(tái)輸出,顯示修改成功
[圖片上傳失敗...(image-da361-1523429930821)]
二. 方法交換(常用來hock/埋點(diǎn)等)
-
在Person中新增2個(gè)方法
- (void)firstMethod { NSLog(@"1st method has been called"); } - (void)secondMethod { NSLog(@"2nd method has been called"); }
-
實(shí)現(xiàn)方法交換
- (void)exchangeMethod { /// 獲取方法 Method m1 = class_getInstanceMethod([self.person class], @selector(firstMethod)); Method m2 = class_getInstanceMethod([self.person class], @selector(secondMethod)); /// 交換方法 method_exchangeImplementations(m1, m2); }
-
分別在交換前后調(diào)用
firstMethod
和secondMethod
, 查看控制臺(tái)輸出[圖片上傳失敗...(image-a492d2-1523429930821)]
三. 動(dòng)態(tài)添加方法
-
添加方法
- (void)addMethod { /// "v@:@" v表示void, @表示id類型, :表示SEL class_addMethod([self.person class], @selector(run:), (IMP)run, "v@:@"); } void run(id self, SEL _cmd, NSString *miles) { NSLog(@"Tome run %@ miles", miles); } - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { [self addMethod]; if ([self.person respondsToSelector:@selector(run:)]) { [self.person performSelector:@selector(run:) withObject:@"1"]; } else { NSLog(@"Method named run: is not been defined!"); } }
-
查看輸出
[圖片上傳失敗...(image-9484c4-1523429930821)]
四. 使用關(guān)聯(lián)屬性給類型添加屬性
-
給Person類添加nick屬性
@property (copy, nonatomic) NSString *name; - (void)firstMethod { NSLog(@"1st method has been called"); } - (void)secondMethod { NSLog(@"2nd method has been called"); }
-
調(diào)用屬性
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { self.person.nick = @"Homer Lynn"; NSLog(@"%@", self.person.nick); }
-
查看輸出
[圖片上傳失敗...(image-7b5e8c-1523429930821)]