首页 > 编程知识 正文

messaging连不上,还有什么动物用什么传递消息

时间:2023-05-05 03:44:13 阅读:167529 作者:4534

本章介绍如何将消息表达式转换为objc_msgSend函数调用,以及如何按名称引用方法。 下面介绍了如何利用objc_msgSend以及如何避免动态绑定

objc_msgSend函数位于Objective-C中,在运行时之前不会将消息绑定到方法的实现。 编译器转换消息表达式,并使用、

[ receiver消息]

调用消息行数objc_msgSend。 此函数需要方法选择器作为两个主要参数:收件人和消息中的方法名称。

objc_msgsend(receiver,selector ) )。

传递给消息的所有参数都可以用objc_msgSend处理。

objc_msgsend(receiver,selector,arg1,arg2,)

消息传递函数支持动态绑定。

首先,获取选择器指示的程序(方法实现)。 因为相同的方法可以在不同的类别中分别实现,所以取得的具体程序取决于接收机的类别。 然后,调用程序,传递接收对象(数据指针)和方法指定的参数。 最后,将程序的返回值作为自己的返回值传递。 注意:编译器将生成消息传递函数。 不能在代码中直接调用。

消息传递的关键是编译器编译每个类和对象的结构。 每个类结构包括以下两个基本元素:

指向父类的指针Dispatch表类。 此表中的记录可以将方法选择器与指定类方法的地址相关联。 setorigin:3360方法的选择器与setorigin33603360地址(程序实现)相关,而display方法的选择器与的display地址相关。 等新对象时,将分配内存并初始化实例变量。 首先,对象变量是指向类结构的指针。 此指针称为isa,通过该类,对象可以访问该类以及该对象继承的所有类。

注意: isa指针不是语言严格意义的一部分,但它是使用Objective-C运行时系统所需的对象。 对象必须与结构定义中的struct objc _ object (在objc/objc.h中定义)等效。 但是,很少需要创建自己的根对象和从NSObject或NSProxy继承的对象,而是自动存在isa变量。

类元素和对象结构如图3-1所示。

图3-1消息传递框架

将消息发送到对象时,消息传递函数会遵循对象的isa指针。 此指针指向类结构,然后在dispatch表中查找方法选择器。 如果找不到选择器,objc_msgSend会根据指向父类的指针,尝试在dispatch表中找到该选择器。 找不到选择器。 objc_msgSend将搜索类的层次结构直到NSObject类。 导航到选择器时,函数将调用表中的方法,并将其传递给传入对象的数据结构。

在运行时选择这样实现的方法。 或者,在面向对象编程术语中,动态绑定到消息。

运行时系统缓存使用的方法的选择器和地址,以加快消息传递过程。 每个类都有单独的缓存,可以包含用于定义继承方法和类中方法的选择器。 在查找dispatch表之前,消息传递程序首先检查目标类(理论上是可能再次使用的方法)的高速缓存。 如果方法选择器位于高速缓存中,则消息传递会比函数调用稍慢。 在程序足够长的时间来“预热”缓存后,发送的大多数消息都可以找到缓存方法。 程序运行时,缓存会动态适应新消息。

使用隐藏参数检测objc_msgSend实现方法的程序,调用该程序并传递消息中的所有参数。 以下两个隐藏参数也传递给程序。

接收对象方法选择器这些参数为每个方法实现提供有关调用它们的消息表达式的明确信息。 它们被视为“隐藏”,因为它们没有在方法定义代码中声明。 编译代码时,它将插入到实现中。

虽然没有明确声明这些参数,但是源代码可以引用接收对象的实例变量。 方法以self形式引用传入对象,并使用自己的选择器作为_cmd。 在以下示例中,_cmd引用strange方法的选择器,而self引用接收strange消息的对象。

- strange { id target=getthereceiver (; SEL method=getTheMethod (; 目标==自||method==_ cmd )返回nil; return [ targetperformselector : method ]; }

Self对两个参数更方便。 实际上,传入对象的实例变量可用于方法定义。

获取方法地址以避免动态绑定的唯一方法是获取方法的地址,然后直接调用它,就像它是函数一样。 如果特定方法连续执行多次,并且每次执行该方法时都希望避免消息传递开销,则可以在极少数情况下执行此方法。

NSObject类可以定义methodForSelector:方法,访问指向实现该方法的程序的指针,然后使用指针调用该程序。 methodForSelector:指针的返回值必须指向适当的函数类型。 必须包含返回值和参数类型。

以下示例说明了程序如何实现setFilled:方法。

void(*setter ) ) id、SEL、BOOL; int i; setter=(void(* ) id,SEL,BOOL ) [ targetmethodforselector : @ selector ) setfilled3360]; for(I=0; i 1000; I ) setter(targetlist[I],@selector ) setfilled3360 ),YES );

前两个参数传递给接收对象(self )的程序和方法选择器(_cmd )。 这些参数在方法语法中是隐藏的,但如果方法作为函数调用,则必须是显式的。

通过使用methodForSelector:方法避免动态绑定,可以大大节省传输消息所需的时间。 但是,只有在特定消息多次重复时(如上述for循环),节约时间才具有重要意义。

注意: Cocoa运行时系统提供methodForSelector:方法。 此方法不是Objective-C语言本身的特性。

官方地址:

3359 developer.apple.com/library/IOs/documentation/cocoa/conceptual/objcruntimeguide/articles/ocrthowmesssaaasare

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。