返回

OC底层探究之动态方法决议的剖析

IOS

一、方法找不到的报错底层原理

当调用一个只有声明而没有实现的方法时,就会抛出经典错误:unrecognized selector sent to instance。要理解这个错误的缘由,就需要深入了解Objective-C中的消息发送机制。

1. 消息发送机制

在Objective-C中,对象的方法调用不是通过直接调用函数指针的方式实现的,而是通过消息发送机制。当发送一条消息给对象时,系统会首先查找该对象是否实现了这个方法,如果没有,则会继续向上查找该对象的父类,依次向上查找直到找到实现该方法的类为止。如果在整个继承链中都找不到该方法的实现,就会抛出unrecognized selector sent to instance的错误。

2. 运行时的作用

Objective-C的运行时库在消息发送机制中扮演着重要的角色。运行时库负责动态查找方法的实现,并在方法调用时将消息转发给相应的实现。运行时库还提供了很多其他功能,比如动态添加方法、动态生成类等,这些功能都依赖于动态方法决议机制。

3. ObjC.msgSend的实现原理

ObjC.msgSend是Objective-C中发送消息的底层实现。当发送一条消息给对象时,编译器会将消息编译成ObjC.msgSend的调用,ObjC.msgSend函数会根据消息中的选择器(selector)和对象类型(class)查找该方法的实现,然后将消息转发给相应的实现。

二、动态方法决议的步骤

1. 消息的发送

当调用一个对象的方法时,编译器会将消息编译成ObjC.msgSend的调用。ObjC.msgSend函数会根据消息中的选择器和对象类型查找该方法的实现。

2. 方法的查找

ObjC.msgSend首先会检查对象是否实现了该方法。如果实现了,则直接调用该方法的实现。如果没有实现,则会继续向上查找该对象的父类,依次向上查找直到找到实现该方法的类为止。

3. 方法的调用

如果在整个继承链中都找不到该方法的实现,则会抛出unrecognized selector sent to instance的错误。否则,ObjC.msgSend会将消息转发给找到的实现,并执行该方法。

三、动态方法决议的应用场景

动态方法决议在Objective-C中有着广泛的应用,比如:

1. 方法转发

当一个对象没有实现某个方法时,可以通过方法转发将该消息转发给另一个对象来处理。这通常用于实现多态性,比如一个父类定义了一个方法,而它的子类可以重写该方法以提供不同的实现。

2. 消息代理

消息代理是一种设计模式,它允许一个对象将消息委托给另一个对象来处理。这通常用于实现松耦合,比如一个对象可以将消息委托给另一个对象来处理用户交互。

3. 运行时编程

动态方法决议是运行时编程的基础。通过动态方法决议,可以动态地添加方法、动态生成类等,从而实现更加灵活的编程。

结语

动态方法决议是Objective-C中一项强大的特性,它使得Objective-C具有很强的动态性。理解动态方法决议的原理可以帮助我们更好地理解Objective-C的底层实现,并编写出更加健壮、灵活的代码。