Objective c ';调用方法';或';发送消息';在目标C中

Objective c ';调用方法';或';发送消息';在目标C中,objective-c,javascript,Objective C,Javascript,在C或任何基于ECMAscript的语言中,您可以对对象“调用公共方法或函数”。但是在Objective C的文档中,没有公共方法调用,只有消息的发送 认为在ObjC中“发送消息”实际上是在“调用对象上的公共方法”有什么不对吗?在我的Java课程中学习过这一点。我想说的是,它们只在多线程场景中存在实际差异,在多线程场景中,消息传递是一种非常合法且经常使用的技术。理论上,它们是不同的 实际上,没有那么多 它们的不同之处在于,在Objective-C中,对象可以选择不响应消息,或者将消息转发到不同的

在C或任何基于ECMAscript的语言中,您可以对对象“调用公共方法或函数”。但是在Objective C的文档中,没有公共方法调用,只有消息的发送


认为在ObjC中“发送消息”实际上是在“调用对象上的公共方法”有什么不对吗?

在我的Java课程中学习过这一点。我想说的是,它们只在多线程场景中存在实际差异,在多线程场景中,消息传递是一种非常合法且经常使用的技术。

理论上,它们是不同的

实际上,没有那么多

它们的不同之处在于,在Objective-C中,对象可以选择不响应消息,或者将消息转发到不同的对象,或者其他任何东西。在像C这样的语言中,函数调用实际上只是跳到内存中的某个位置并执行代码。不涉及动态行为

但是,在标准用例中,当您向对象发送消息时,通常会调用消息所表示的方法。因此,大约99%的情况下,发送消息会导致调用方法。因此,当我们真正的意思是“发送消息”时,我们经常说“调用方法”。所以实际上,它们几乎总是一样的,但它们不一定是一样的

不久前,我对这个话题充满了哲理,并在博客上对此发表了看法:

编辑

要直接回答您的问题,通常说“调用方法”而不是“发送消息”没有什么错。然而,重要的是要理解,存在着非常显著的实现差异


(顺便说一句,我个人的偏好是说“在对象上调用方法”)

不,这样想完全没有错。它们被称为消息,因为它们是函数之上的抽象层。其中一部分来自Objective C的类型系统。更好地理解信息有助于:

(我挑选了一些更相关的问题)

函数的内部名称是 很少直接使用。通常地 消息被转换为函数 在Objective-C中定义的调用 运行库。不一定 在链接时知道将使用哪种方法 被称为是因为 接收方(正在发送的对象) 消息)直到 运行时

同一条:

目标C模型 面向对象编程是基于 关于向对象传递消息 实例。在目标C中,一个没有 调用一个方法;一个人发出信息。对象所指向的对象 消息已定向-接收器- 不保证对 消息,如果它没有,它只是 引发了一个异常。 Smalltalk风格的编程 允许消息未执行, 方法解决了它的问题 在运行时实现。对于 例如,可以将消息发送到 对象的集合,只有 预计会有一些人作出回应, 无需担心生成运行时 错误。(可可平台需要 这样做的好处是,在一个 Cocoa应用程序被发送到 awakeFromNib:消息作为 应用程序启动。对象可能会 通过执行任何 启动时需要初始化。) 消息传递也不需要 在编译时定义一个对象 时间


由于Objto-C的动态消息调度,消息发送实际上不同于调用C函数或C++方法(尽管最终将调用C函数)。消息通过选择器发送到接收对象,接收对象通过调用

IMP
(C函数指针)或将消息转发到其超类来响应消息。如果继承链中没有类响应消息,则会引发异常。还可以截获消息并将其转发到完全不同的类(这就是
NSProxy
子类所做的)

在使用Objective-C时,消息发送和C++风格的方法调用之间没有太大区别,但据我所知,消息传递系统有一些实际意义:

  • 由于消息处理发生在运行时,而不是编译时,因此编译时无法知道类是否响应任何特定消息。这就是为什么在拼写错误的方法时,通常会收到编译器警告而不是错误
  • 您可以安全地将任何消息发送到
    nil
    ,允许使用类似
    [foo release]
    的习惯用法,而无需担心检查NULL
  • 正如@CrazyJugglerDrummer所说,消息调度允许您一次向许多对象发送消息,而不必担心它们是否会响应。这允许非正式协议和向容器中的所有对象发送消息
  • 我不是100%确定这一点,但我认为通过动态消息调度可以实现类别(向现有类添加方法)
  • 消息发送允许消息转发(例如使用
    NSProxy
    子类)
  • 消息发送允许您进行有趣的低级黑客攻击,例如方法swizzling(在运行时交换方法的实现)
    在C函数调用中,编译器将选择器替换为对函数的调用,并响应函数调用跳转执行

    在Objective-C中,方法动态绑定到消息,这意味着方法名称在运行时解析为实现。具体来说,在运行时检查对象,以查看它是否包含指向给定选择器的实现的指针

    因此,Objective-C允许您在运行时加载和链接新的类和类别,并执行诸如滑动、类别、对象代理等技术。所有这些在中国都是不可能的