iOS_Runtime3_动态添加方法

  • 当调用一个未实现的对象方法,或者说发送未知的消息给接收者时候,消息的接受者会调用+ (BOOL)resolveInstanceMethod:(SEL)sel;
  • 当调用一个未实现的类方法,或者说发送未知的消息给接收者时候,消息的接受者会调用+ (BOOL)resolveClassMethod:(SEL)sel;
  • 任何一个方法默认都有两个隐式参数(id self, SEL _cmd),其中self指代调用此方法的对象,_cmd指代方法的编号,经过NSStringFromSelector(_cmd)处理打印结果为方法名。
  • 为类添加方法的方法:BOOL class_addMethod(Class cls, SEL name, IMP imp,const char *types)。其中参数一:为哪个类添加方法;参数二:添加什么方法;参数三:方法实现 => 函数 => 函数入口 => 函数名;参数四:方法类型:void用v来表示,id参数用@来表示,SEL用:来表示。

动态添加方法代码示例如下:

// UIImage+Image.h

// 未实现的对象方法
- (void)clearImage;

// UIImage+Image.m
#pragma mark - 动态添加方法
// 对象方法未实现,会调用此类方法
+ (BOOL)resolveInstanceMethod:(SEL)sel{
//    [NSStringFromSelector(sel) isEqualToString:@"clearImage"]; // 判断方式1
    // 判断方式2
    if (NSSelectorFromString(@"clearImage") == sel) {
        // 为类添加方法
        class_addMethod(self, sel, (IMP)clearImage, "v@:@");
        return YES;
    }
    return [super resolveInstanceMethod:sel];
}
// 此方法即(IMP)clearImage
// 任何一个方法默认都有两个隐式参数(`id self, SEL _cmd`),其中self指代调用此方法的对象,_cmd指代方法的编号,经过`NSStringFromSelector(_cmd)`处理打印结果为方法名。
void clearImage(id self, SEL _cmd, NSNumber *number){
    NSLog(@"clearImage for %@--%@--%@", self,NSStringFromSelector(_cmd),number);
}

// 如果是类方法未实现,则会调用下述方法:
/*
+ (BOOL)resolveClassMethod:(SEL)sel{
}
*/
// 调用示例:
UIImage *image = [[UIImage alloc]init];
[image clearImage];
// 输出: clearImage for <UIImage: 0x608000282760>, {0, 0}--clearImage--<UIImage: 0x608000282760>, {0, 0}

[image performSelector:@selector(clearImage) withObject:@"kkkk"];
// 输出:clearImage for <UIImage: 0x608000282760>, {0, 0}--clearImage--kkkk
// 方法`performSelector:withObject:`表示去执行某个方法aSelector,传递参数object

使用场景:
- 如果一个类方法非常多,加载类到内存的时候也比较耗费资源,需要给每个方法生成映射表,可以使用动态给某个类,添加方法解决。
- 使用performSelector:withObject调用方法,主要是为了调用动态添加的方法。


iOS_Runtime1_消息发送机制

iOS_Runtime2_方法交换

iOS_Runtime4_动态添加属性

iOS_Runtime5_消息转发

iOS_Runtime6_字典转化为模型应用


代码地址:
https://github.com/FlyingKuiKui/RunTime.git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值