method-swizzling 详解 和使用

本文介绍了Objective-C中的Method Swizzling技术,这是一种在运行时改变方法实现的手段。通过`method_exchangeImplementations`、`class_replaceMethod`和`method_setImplementation`等方法,可以修改类的选择器到IMP的映射。通常在`+load`方法中执行,确保只执行一次,并使用`dispatch_once`保证安全性。Method Swizzling常用于日志统计、异常处理,如防止数组越界崩溃。文章列举了多个使用场景,包括替换`dealloc`方法、安全访问数组和字典,以及处理未识别选择器错误。需要注意的是,不当使用可能引发不可预知的错误,需要谨慎操作。
摘要由CSDN通过智能技术生成

简介

在Objective-C中调用一个方法,其实是向一个对象发送消息,查找消息的唯一依据是selector的名字。利用Objective-C的动态特性,可以实现在运行时偷换selector对应的方法实现。
每个类都有一个方法列表,存放着selector的名字和方法实现的映射关系。IMP有点类似函数指针,指向具体的Method实现。
我们可以利用 method_exchangeImplementations 来交换2个方法中的IMP,
我们可以利用 class_replaceMethod 来修改类,
我们可以利用 method_setImplementation 来直接设置某个方法的IMP,
通过上边的方法,可以把类的调度表(dispatch table)中选择器到最终函数间的映射关系 替换。就相当于把IMP 的只想替换了。

  • swizzling 需要在 + (void)load{}中使用
  • swizzling 需要保证只执行一次。 需要使用 dispatch_once;
  • load 和initialize区别:load是只要类所在文件被引用就会被调用,而initialize是在类或者其子类的第一个方法被调用前调用。所以如果类没有被引用进项目,就不会有load调用;但即使类文件被引用进来,但是没有使用,那么initialize也不会被调用。

使用场景 (1)

需要统计事件,或者需要输出Log的时候,可以使用。比如在delloc中,输出log。告诉我们哪个类释放了。

+ (void)swizzWithClass:(Class)class originSel:(SEL)originSel newSel:(SEL)newSel{

Method originM = class_getInstanceMethod(class, originSel);
Method newM = class_getInstanceMethod(class, newSel);

IMP newImp =  method_getImplementation(newM);

BOOL addMethodSucess = class_addMethod(class, newSel, newImp, method_getTypeEncoding(newM));

if (addMethodSucess) {
    class_replaceMethod(class, originSel, newImp, method_getTypeEncoding(newM));
}else{
    method_ex
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值