Runtime梳理
来源:互联网 发布:新西兰移民 知乎 编辑:程序博客网 时间:2024/06/05 11:09
以下主要从编码实现来学习Runtime
一、动态变量的控制
1.场景
有一个Student类,有一个name属性。动态将学生小明的名字改为小李
2.步骤
动态获取Student类中的所有属性(包括私有属性)
Ivar *ivar = class_copyIvarList([xiaoMing class], &count);
遍历属性找到对应的name字段
const char *varName = ivar_getName(var);
修改对应的字段值成小李
object_setIvar(xiaoMing,var,@"小李");
3.完整代码
- (void)method{Student *xiaoMing = [Student new];xiaoMing.name = @"小明"; unsigned int count = 0; Ivar *ivar = class_copyIvarList([self.xiaoMing class], &count); for (int i = 0; i<count; i++) { Ivar var = ivar[i]; const char *varName = ivar_getName(var); NSString *name = [NSString stringWithUTF8String:varName]; if ([name isEqualToString:@"_name"]) { object_setIvar(self.xiaoMing, var, @"小李"); break; } }}
二.动态交换方法
1、场景
Student类中有两个方法method1 和method2 。调用method1打印调用了方法一,调用method2打印调用了方法二,经过Runtime处理
实现调用method2打印调用了方法一,调用method1打印调用了方法二
2、实现步骤
动态找到method1和method2(这里是动态获取实例方法的函数)
Method m1 = class_getInstanceMethod([xiaoMing class], @selector(method1));Method m2 = class_getInstanceMethod([xiaoMing class], @selector(method2));
交换两个方法
method_exchangeImplementations(m1, m2);
3、完整代码
-(void)exchangeMethod{ Method m1 = class_getInstanceMethod([xiaoMing class], @selector(method1)); Method m2 = class_getInstanceMethod([xiaoMing class], @selector(method2)); method_exchangeImplementations(m1, m2);[xiaoMing method1];[xiaoMing method2];}
三.动态添加方法
1.场景
Student类中没有play这个方法,由于特殊需要被Runtime添加了一个play方法,再调用这个方法。
2.实现步骤
动态给Student类中添加play方法
class_addMethod([xiaoMing class], @selector(play), (IMP)playStudent, "v@:");
参数说明:
(IMP)playStudent 意思是playStudent的地址指针;
“v@:” 意思是,v代表无返回值void,如果是i则代表int;
@代表 id sel; : 代表 SEL _cmd;
“v@:@@” 意思是,两个参数的没有返回值。
用play方法响应事件
[xiaoMing performSelector:@selector(play)];//编写playStudent的实现:void playStudent(id self,SEL _cmd){ NSLog(@"happy play"); }
备注:
1.void playStudent(id self,SEL _cmd)是函数。
2.必须有两个指定参数(id self,SEL _cmd)
3.完整代码
-(void)takePlay{ class_addMethod([xiaoMing class], @selector(play), (IMP)playStudent, "v@:"); if ([xiaoMing respondsToSelector:@selector(play)]) { [xiaoMing performSelector:@selector(play)]; } else{ NSLog(@"Sorry,I don't know"); }}void playStudent(id self,SEL _cmd){ NSLog(@"happy play");}
4.动态为Category扩展属性
1.场景
众所周知在给OC的分类中添加声明@property属性,编译通过,但无法赋值,取值。那么Runtime如何实现可以赋值,取值
以Student类为例,给其分类中动态添加nick属性
2.实现步骤
声明nick属性
#import "Student.h"@interface Student(TG)@property(nonatomic,copy) NSString *nick;@end//动态添加属性和实现方法@implementation Student (TG)char cNick;-(void)setNick:(NSString *) nick{ objc_setAssociatedObject(self, &cNick, nick, OBJC_ASSOCIATION_COPY_NONATOMIC);}-(NSString *)chineseName{ return objc_getAssociatedObject(self, &cNick);}@end//给nick属性赋值,取值- (void)show{xiaoMing.nick = @"豆豆"; NSLog(@"nick name is %@",xiaoMing.nick);}
重要应用有MjExtesion,AFNetworking框架的应用等
———————–陈洪鑫———————
0 0
- Runtime梳理
- Runtime梳理
- 谈Runtime机制和使用的整体化梳理
- 谈Runtime机制和使用的整体化梳理
- 谈Runtime机制和使用的整体化梳理
- 谈Runtime机制和使用的整体化梳理
- 谈Runtime机制和使用的整体化梳理
- 谈Runtime机制和使用的整体化梳理
- 谈Runtime机制和使用的整体化梳理
- 谈Runtime机制和使用的整体化梳理
- 谈Runtime机制和使用的整体化梳理
- 谈Runtime机制和使用的整体化梳理
- 谈Runtime机制和使用的整体化梳理
- 梳理
- 梳理
- 梳理
- 梳理
- 梳理
- 添加Action Provider 添加导航Tabs 自定义ActionBar样式
- web开发之css知识点理解与回顾(一)对齐
- MacOS下hls/rtmp直播服务器搭建(包括推流)
- 类与对象二(基础)
- centos7安装memcached及配置等
- Runtime梳理
- 大数据—Spark简介
- 【Python】pdf文件逐页转图片/修改图片存储大小脚本
- AlertDialog三种退出方式分析
- 【USACO】2004 Open MooFest 奶牛集会
- 分类算法SVM(支持向量机)
- MyBatis的增删改查基本操作
- 图形化脚本1.dialog工具
- 4 js面向对象基础 - 预解析,词法作用域,作用域链