在Objective C中,您具有将消息发送到其他对象的概念,并且,这与以C#和Java这样的语言进行的方法调用非常相似。
但是,细微的差别到底是什么?在考虑我的代码时,我应该如何考虑消息传递?
注意:在这里,我只是一名C#/ Java开发人员,试图了解有关Objective C的一些概念。
在Objective C中,您具有将消息发送到其他对象的概念,并且,这与以C#和Java这样的语言进行的方法调用非常相似。
但是,细微的差别到底是什么?在考虑我的代码时,我应该如何考虑消息传递?
注意:在这里,我只是一名C#/ Java开发人员,试图了解有关Objective C的一些概念。
Answers:
消息是选择器的名称,以及该选择器的参数。
选择器是一个符号。
方法是选择器标识的类中的一段代码。
换句话说,[foo bar: baz]
说“将@selector(bar:)
带有参数调用的消息发送baz
到对象foo
。您可以将该消息发送到许多不同的对象。
相反,方法 bar:
的Foo
可能看起来像
-(int)bar:(int)n {
return n + 1;
}
但FooTwo
可能看起来像
-(int)bar:(int)n {
return n + 2;
}
(我希望我的语法正确;自从我上次接触Objective-C已经有一段时间了。)
发送消息时,Objective-C内核将消息调度到该消息,foo
以确定它是否理解该消息。它根据是否可以找到该选择器标识的方法来决定。
具有相同名称的两种方法和一条消息。
一个对象也可以简单地将一条特定的消息(或一组消息)转发到另一个对象进行处理。在这种情况下,您将消息发送到此代理对象,该对象没有与该消息匹配的方法,并且代理将消息转发到其包装的对象。
从纯粹的理论观点来看,两者之间根本没有区别-有大量的正式证据表明两者是完全等同的,并且任何一个都可以在另一个方面完全实现。
从稍微不太理论的观点来看,存在一个可能的差异:在典型的实现中,虚拟函数表是静态分配的,而每个vtable的内容在编译时是固定的。相比之下,消息查找通常使用某种类似于地图的对象来完成,该对象通常是动态的,这意味着您可以在运行时对其进行修改。这使得在现有类中向消息添加新响应相对容易。不幸的是,在大多数情况下,这仍然是理论上的。首先,你基本上处理自修改代码,大多数人决定是一个非常糟糕的主意一个长过去。其次,要使其非常有意义,您非常需要能够将新代码编译到现有类中,以响应您支持的新消息。否则,您几乎可以获得为现有方法动态添加新名称的能力。
正如上一段末所暗示的那样,从实际的角度来看,两者之间几乎没有什么区别。它们只是支持后期绑定的两种(非常轻微)不同的方式。尽管基于消息的查找通常要慢一些,但要使差异真正重要将是非常不寻常的。对于大多数实际目的,它们只是完成同一件事的两种不同方式。
通常,方法调用是在编译时解决的(除非您在Java中使用反射),而Objective C中的消息是在运行时调度的。
消息要么由内核处理,要么由语言本身处理(例如,对于ObjC,有一个很小的汇编代码可以完成)。
例如,在linux内核中,消息是通过系统调用/函数完成的:如果您搜索unix系统编程,则可以找到它们。
方法调用和消息之间的核心区别是:
方法调用仅在您的代码中发生:在ASM中,它由传递的参数的PUSH转换。
内核消息主要是发送到内核的内容,该消息将被跟踪并发回特定进程。我可能会将它们误认为管道,但无论如何:知道已经有了一种机制,可以让您同时运行多个程序并同时进行通信。当然,不要希望这在Windows或其他OS上能以相同的方式工作。