Runtime梳理

以下主要从编码实现来学习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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值