在目标C中"调用方法"或"发送消息"

Bac*_*alo 51 javascript objective-c

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

当你在ObjC中"发送消息"时,你实际上是在"在对象上调用公共方法"时,有什么不对吗?

Dav*_*ong 56

从理论上讲,它们是不同的.

实际上,并非如此.

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

但是,在标准用例中,当您向对象发送消息时,通常最终会调用所表示的消息的方法.因此,大约99%的时间,发送消息将导致调用方法.因此,当我们真正意味着"发送消息"时,我们经常说"调用方法".实际上,它们几乎总是一样的,但它们并非必须如此.

不久前,我对这个主题进行了哲学思考,并在博客上发表了博客:http: //davedelong.tumblr.com/post/58428190187/an-observation-on-objective-c

编辑

要直接回答你的问题,说"调用方法"而不是"发送消息"通常没有错.但是,重要的是要了解实施差异非常大.

(另外,我个人的偏好是说"在一个对象上调用一个方法")


sho*_*sti 20

由于Objective-C的动态消息传递调度,消息发送实际上与调用C函数或C++方法不同(尽管最终会调用C函数).消息通过选择器发送到接收对象,接收对象通过调用IMP(C函数指针)或通过将消息转发到其超类来响应消息.如果继承链中没有类响应消息,则抛出异常.拦截消息并将其转发到完全不同的类(这是NSProxy子类的作用)也是可能的.

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

  1. 由于消息处理是在运行时发生的,而不是编译时间,因此没有编译时方法来了解类是否响应任何特定消息.例如,这就是为什么在拼写错误方法时通常会收到编译器警告而不是错误.
  2. 您可以安全地发送任何消息nil,允许成语,[foo release]而不必担心检查NULL.
  3. 正如@CrazyJugglerDrummer所说,消息调度允许您一次向大量对象发送消息,而不必担心它们是否会响应它们.这允许非正式协议并将消息发送到容器中的所有对象.
  4. 我不是100%肯定这一点,但我认为通过动态消息调度可以实现类别(向已存在的类添加方法).
  5. 消息发送允许消息转发(例如,使用NSProxy子类).
  6. 消息发送允许您进行有趣的低级别黑客攻击,例如方法调配(在运行时交换方法的实现).

  • 不可否认,我是一名Objective-C新手,但你不是说`[foo release]`? (4认同)