返回

动态方法决议与消息转发之方法决议介绍

IOS

前言

前文介绍的方法的查找流程:快速查找和慢速慢速查找流程。但是并没有讲当方法实现没有找到时,系统是如何处理的,本文将介绍这一部分。

1. 方法决议

当慢速查找没有找到时,进入方法决议阶段——resol

resolution {
  if (class has "prop" prop-list) {
    // 尝试通过使用 Proplist 中的属性查找方法
    return Lookupprop(class prop-list selector)
  } else if (class has "method" method-list) {
    // 尝试通过使用 Methodlist 中的方法查找方法
    return Lookupmethod(class method-list selector)
  } else {
    // 报错:未找到方法
    Error("no such method")
  }
}
Lookupprop(class prop-list selector) {
  for (prop in prop-list) {
    if (prop selector == selector) {
      // 找到属性,返回属性的实现
      return prop
    }
  }
  // 未找到属性,返回 nil
  return nil
}
Lookupmethod(class method-list selector) {
  for (method in method-list) {
    if (method selector == selector) {
      // 找到方法,返回方法的实现
      return method
    }
  }
  // 未找到方法,返回 nil
  return nil
}

如果通过 Proplist 和 Methodlist 都没有找到方法,那么就说明该类中确实没有实现该方法。此时,系统会报错:未找到方法。

2. 消息转发

消息转发是动态方法决议的一种实现方式。在消息转发中,当一个对象接收到一个消息时,它会将该消息转发给另一个对象来处理。这种方式的好处是,它可以使对象之间解耦,从而提高代码的可维护性和复用性。

在 Smalltalk 中,消息转发是通过一种叫做“消息发送”的机制来实现的。消息发送的语法如下:

receiver message arguments

其中,receiver 是消息的接收者,message 是消息的名字,arguments 是消息的参数。

当一个对象收到一个消息时,它会先检查自己是否能够处理该消息。如果能够处理,则直接执行该消息的实现。如果不能处理,则会将该消息转发给另一个对象来处理。

消息转发可以分为两类:

  • 静态消息转发: 静态消息转发是在编译时确定的。也就是说,在编译时就已经知道消息将被转发给哪个对象。
  • 动态消息转发: 动态消息转发是在运行时确定的。也就是说,在运行时才知道消息将被转发给哪个对象。

3. 应用场景

动态方法决议在面向对象编程中有很多应用场景,例如:

  • 多态: 多态是面向对象编程中的一项重要特性。它允许父类和子类的对象都可以响应相同的消息,但是执行不同的操作。这使得我们可以编写出更灵活和可扩展的代码。
  • 继承: 继承是面向对象编程中的一种关系。它允许子类继承父类的属性和方法。这使得我们可以复用父类中的代码,并扩展父类中的功能。
  • 封装: 封装是面向对象编程中的一项重要原则。它要求将对象的属性和方法隐藏起来,只对外暴露一个接口。这使得我们可以提高代码的安全性