您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > 百科

OC消息发送和转发机制原理

时间:2023-10-13 13:23:02  来源:微信公众号  作者:good7ob

Objective-C(OC)是一门面向对象的编程语言,它在消息传递和方法调用方面具有独特的机制。在OC中,对象通过消息来调用方法,而不是像传统的编程语言那样直接调用函数。本文将深入探讨OC的消息发送和转发机制原理,包括其基本概念、实现过程、代码示例以及实际应用场景。

OC消息发送和转发机制原理

第一步:什么是消息发送和转发机制?

在Objective-C中,对象之间的通信是通过消息传递来实现的。当一个对象想要调用另一个对象的方法时,它会发送一个消息,然后由接收消息的对象来响应这个消息。这种方式与传统的函数调用不同,使得OC具有更高的动态性和灵活性。

消息发送和转发机制分为三个阶段:

  • 消息发送(Message Sending): 当一个对象收到一个消息时,它首先会在自己的方法列表中查找是否有与消息对应的方法。如果找到了,就会执行该方法;如果找不到,就会进入下一阶段。
  • 消息转发(Message Forwarding): 如果对象无法找到与消息对应的方法,它将进入消息转发过程。在这个阶段,对象有机会将消息转发给其他对象。
  • 未知消息处理(Handling Unknown Messages): 如果经过消息转发仍未找到合适的方法,系统将调用-doesNotRecognizeSelector:方法,该方法默认会引发异常,但也可以由开发者进行重写以执行其他操作。

第二步:消息发送的原理

消息发送是OC的核心机制之一,它使得方法的调用更为动态和灵活。消息发送的原理可以概括为以下几个步骤:

  • 创建消息: 当一个对象想要调用方法时,它会创建一个消息,包括消息的接收者、方法名(选择器)以及方法的参数。
  • 查找方法: 对象会在自己的方法列表(方法分发表)中查找是否存在与消息对应的方法。方法分发表是一个映射,将选择器与方法的实现关联起来。
  • 调用方法: 如果找到了与消息对应的方法,对象将直接调用该方法并执行。如果找不到,消息将进入消息转发阶段。

第三步:消息转发的原理

当一个对象无法找到与消息对应的方法时,它会进入消息转发过程。消息转发的原理可以概括为以下几个步骤:

  • 消息转发的开始: 对象收到无法处理的消息后,会调用-forwardingTargetForSelector:方法,该方法允许对象将消息转发给其他对象。如果返回一个有效的对象,则消息将被转发给该对象。
  • 备用接收者: 如果-forwardingTargetForSelector:方法返回nil,对象会继续查找是否存在备用接收者(Alternate Receiver),这通常是另一个对象。备用接收者可以通过覆盖+ (id)forwardingTargetForSelector:(SEL)aSelector类方法来指定。
  • 动态方法解析: 如果没有备用接收者或备用接收者也无法处理消息,对象将调用+resolveInstanceMethod:或+resolveClassMethod:方法来动态添加方法。这允许开发者在运行时为对象添加新方法。
  • 完整的消息转发: 如果前面的步骤都失败,对象将调用-forwardInvocation:方法,将消息以NSInvocation对象的形式传递给该方法。在-forwardInvocation:方法中,开发者可以手动处理消息的转发,包括将消息发送给其他对象或执行其他操作。

第四步:消息发送和转发的代码示例

让我们通过一个简单的代码示例来演示消息发送和转发的过程:

#import <Foundation/Foundation.h>

@interface MyObject : NSObject

- (void)methodA;

@end

@implementation MyObject

- (void)methodA {
    NSLog(@"Method A is called");
}

@end

int mAIn(int argc, const char * argv[]) {
    @autoreleasepool {
        MyObject *obj = [[MyObject alloc] init];
        
        // 调用已存在的方法
        [obj methodA]; // 输出 "Method A is called"
        
        // 调用不存在的方法
        [obj methodB]; // 触发消息转发
        
        // 使用动态方法解析添加方法
        class_addMethod([MyObject class], @selector(methodB), class_getMethodImplementation([MyObject class], @selector(methodA)), "v@:");
        
        // 再次调用方法
        [obj methodB]; // 输出 "Method A is called"
    }
    return 0;
}

在这个示例中,我们首先创建了一个MyObject类,其中包含了methodA方法。然后,我们创建了一个对象obj,并尝试调用methodA方法,这是一个已存在的方法。

接下来,我们尝试调用一个不存在的方法methodB,这将触发消息转发过程。在消息转发过程中,我们使用动态方法解析的方式,将methodB方法的实现与methodA方法的实现关联起来。最后,再次调用methodB方法,它将执行methodA的实现。

第五步:消息发送和转发的实际应用场景

消息发送和转发机制在实际应用中有广泛的用途,以下是一些常见的应用场景:

  • 动态方法解析: 允许在运行时为对象添加新方法,这对于插件系统和模块化开发非常有用。例如,可以根据需要动态地添加或删除插件功能。
  • 消息转发: 可以将消息转发给其他对象,从而实现代理模式、委托模式和责任链模式。这允许对象在无需了解具体实现的情况下,将任务委派给其他对象。
  • 无法修改源代码的情况下扩展功能: 在某些情况下,无法修改类的源代码,但仍需要扩展其功能。消息转发允许我们通过子类或其他方式扩展对象的功能。
  • AOP(面向切面编程): 可以使用消息发送和转发来实现AOP,例如,在方法调用前后添加日志记录、性能监测和异常处理等方面。
  • 未知消息处理: 如果某个对象需要处理未知的消息或命令,可以使用消息转发机制来处理这些情况。例如,一个通用的消息处理器可以根据不同的消息类型执行不同的操作。

第六步:注意事项

在使用消息发送和转发机制时,需要注意以下几点:

  • 性能影响: 消息发送和转发机制可能会带来一定的性能开销,因为它涉及到动态查找方法和传递消息。在需要高性能的场景中,应谨慎使用。
  • 命名规范: 为了避免混淆和错误,应遵循良好的方法命名规范,以确保方法名与消息名称一致。
  • 动态方法解析和消息转发的复杂性: 动态方法解析和消息转发是强大的机制,但也复杂。在使用时需要仔细考虑和测试,以确保正确处理未知消息。
  • 不要滥用: 消息发送和转发机制是强大的工具,但不应滥用。它通常应该作为一种后备机制,用于处理特定情况下的消息,而不是常规编程的方式。

第七步:总结

OC的消息发送和转发机制是这门编程语言的一个核心特性,它使得方法调用更为动态和灵活。理解消息发送和转发的原理,可以帮助开发者更好地利用这一机制,实现面向对象编程的设计模式和思想。

消息发送和转发机制具有广泛的实际应用场景,包括动态方法解析、消息转发、AOP编程、无法修改源代码的扩展功能等。通过深入研究和实践,开发者可以更好地掌握消息发送和转发机制,提高代码的灵活性和可扩展性,同时确保应用程序的可维护性和稳定性。这一机制使OC成为一门强大的面向对象编程语言,值得开发者深入学习和探索。



Tags:OC   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
Docker 和传统虚拟机有什么区别?
我有一个程序员朋友,他每年情人节都要送女朋友一台服务器。他说:“谁不想在过节当天收到一台 4核8g 的服务器呢?”“万一对方不要,我还能留着自己用。” 给他一次过节的机会,他能...【详细内容】
2024-03-26  Search: OC  点击:(12)  评论:(0)  加入收藏
20k级别前端是怎么使用LocalStorage的,想知道吗?
当咱们把咱们想缓存的东西,存在localStorage、sessionStorage中,在开发过程中,确实有利于咱们的开发,咱们想看的时候也是一目了然,点击Application就可以看到。前言大家好,我是林...【详细内容】
2024-03-26  Search: OC  点击:(11)  评论:(0)  加入收藏
美国如何打击加密货币逃税?一文梳理OysterProtocol与BrunoBlock逃税案
作者 | TaxDAO-Ray、TaxDAO-Leslie2018年10月,加密平台Oyster Protocol遭遇了一场严重的危机,其创始人Bruno Block(真实名字Amir Bruno Elmaani)利用智能合约中的漏洞,私自铸造了...【详细内容】
2024-03-26  Search: OC  点击:(11)  评论:(0)  加入收藏
掌握Docker网络驱动程序:优化容器通信
Docker为在容器内包装、交付和运行应用程序提供了一个强大的平台,从而彻底改变了容器化。网络是容器化的重要组成部分,Docker提供了各种网络驱动程序来支持容器之间的通信以...【详细内容】
2024-03-22  Search: OC  点击:(10)  评论:(0)  加入收藏
如何基于Docker镜像逆向生成Dockerfile
引言你是否曾经遇到过一个想要使用的 Docker 镜像,但却无法修改以适应你的特定需求?或者你可能发现了一个喜欢的 Docker 镜像,但想要了解它是如何构建的?在这两种情况下,将 Docke...【详细内容】
2024-03-07  Search: OC  点击:(22)  评论:(0)  加入收藏
详解基于SpringBoot的WebSocket应用开发
在现代Web应用中,实时交互和数据推送的需求日益增长。WebSocket协议作为一种全双工通信协议,允许服务端与客户端之间建立持久性的连接,实现实时、双向的数据传输,极大地提升了用...【详细内容】
2024-01-30  Search: OC  点击:(9)  评论:(0)  加入收藏
Docker与Docker Compose入门:释放你应用部署的威力
今天给大家介绍一项强大而有趣的技能,那就是使用 Docker 和 Docker Compose 来释放你的应用部署的威力!无论你是一名开发人员还是系统管理员,掌握这个技能都将为你的工作带来巨...【详细内容】
2024-01-17  Search: OC  点击:(65)  评论:(0)  加入收藏
Docker镜像与容器的交互及在容器内部执行代码的原理与实践
Docker作为一种流行的容器技术,已经成为现代应用程序开发和部署的重要工具。在Docker中,镜像是构建和运行容器的基础,而容器则是基于镜像创建的可执行实例。Docker镜像与容器的...【详细内容】
2024-01-10  Search: OC  点击:(76)  评论:(0)  加入收藏
如何在 Ubuntu 上安装 Docker
使用 Docker 意味着开启一个新的计算领域,但如果你刚刚开始使用 Docker,安装可能看起来是一项艰巨的任务。在 Ubuntu 上安装 Docker 有两种推荐的方法: 从 Ubuntu 的仓库安装 D...【详细内容】
2024-01-04  Search: OC  点击:(124)  评论:(0)  加入收藏
大白话设计RocketMQ延迟消息
延迟消息一般用于:提前发送消息,延迟一段时间后才需要被处理的场景。比如:下单半小时后还未支付,则取消订单 释放库存 等。RocketMQ的延迟消息使用上非常便捷,但是不支持任意时间...【详细内容】
2023-12-27  Search: OC  点击:(102)  评论:(0)  加入收藏
▌简易百科推荐
用于人工智能开发的主流编程语言都有哪些?
在人工智能开发领域,编程语言的选择至关重要。目前,主流的编程语言主要包括Python、Java、C++、JavaScript和Swift等。这些语言各具特色,适用于不同的人工智能开发场景。首先,Py...【详细内容】
2024-01-31    简易百科  Tags:编程语言   点击:(129)  评论:(0)  加入收藏
探究微处理器开发中的汇编语言的优势与挑战
在计算机编程中,汇编语言是一种低级语言,它可以直接控制计算机的硬件资源。与高级语言相比,汇编语言具有更高的运行效率和更好的控制能力,但同时也更加复杂和难以理解和维护。在...【详细内容】
2023-12-19  松鼠宝贝    Tags:汇编语言   点击:(98)  评论:(0)  加入收藏
选择适合微服务的编程语言,让你的工作事半功倍!
讨论编程语言就像是一场政治辩论。每个开发者都会过分捍卫他/她所使用的编程语言。然而,编程语言应该被看作是它们真正是的东西,即一种工作工具。每种编程语言都有特定的目的...【详细内容】
2023-12-14  爱发白日梦的后端  微信公众号  Tags:编程语言   点击:(177)  评论:(0)  加入收藏
编程语言大比拼:Python、Java、C、C++、Go 实现 'Hello World' 和九九乘法表"
应该90%的IT专业的朋友写的第一段代码就是打印"holle world",每个大学老师都会通过这个方式吸引你对课程产生兴趣。也许有的朋友学的是JAVA开发,有的学的是c,在几年前应该很...【详细内容】
2023-12-11  IT仔的笔记本  微信公众号  Tags:编程语言   点击:(216)  评论:(0)  加入收藏
TypeScript中的null和undefined的区别
在TypeScript中,null和undefined是两个特殊的值,用于表示变量的缺失或未定义。尽管它们在某些情况下可能看起来相似,并且都可以表示"没有值",但它们在语义和用法上存在一些重要...【详细内容】
2023-12-07  科学随想录  微信公众号  Tags:TypeScript   点击:(132)  评论:(0)  加入收藏
面向AI开发的六种最重要的编程语言
作者丨FATIH K&Uuml;&Ccedil;&Uuml;KKARAKURT 译者 | 布加迪审校 | 重楼出品 | 51CTO技术栈(微信号:blog51cto)在AI开发界,你使用的编程语言很重要。每种语言有其独特...【详细内容】
2023-12-07    51CTO  Tags:编程语言   点击:(121)  评论:(0)  加入收藏
NLP问题实战:基于LSTM(RNN)和Transformer模型
译者 | 朱先忠审校 | 重楼简介GPT等语言模型最近变得非常流行,并被应用于各种文本生成任务,例如在ChatGPT或其他会话人工智能系统中。通常,这些语言模型规模巨大,经常使用超过数...【详细内容】
2023-11-29    51CTO  Tags:NLP   点击:(272)  评论:(0)  加入收藏
一文了解低级和高级编程语言
中文是一种尽量用简短文字表达更多含义的语言,所以很多时候一句话的含义很容易曲解成别的意思。最近,有人提出C语言是一种中级语言的概念,所以特意介绍一下低级语言和高级语言...【详细内容】
2023-11-23  数字随行  微信公众号  Tags:编程语言   点击:(232)  评论:(0)  加入收藏
JetBrains 发布 2023 调研报告:77% 开发者使用 ChatGPT
IT之家 11 月 21 日消息,JetBrains 日前公布了《2023 开发人员生态系统现状》调研报告,汇集了来自全球 26,348 位开发者的调研结果。《开发者生态系统现状报告》涵盖广泛的主...【详细内容】
2023-11-21    IT之家  Tags:JetBrains   点击:(236)  评论:(0)  加入收藏
Go vs Rust:文件上传性能比较
一、设置所有测试都在配备16G内存的 MacBook Pro M1 上执行。软件版本为: Go v1.20.5 Rust v1.70.0测试工具是一个基于 libcurl 并使用标准线程的自定义工具,能够发送多部分请...【详细内容】
2023-11-20  技术的游戏  微信公众号  Tags:Rust   点击:(174)  评论:(0)  加入收藏
站内最新
站内热门
站内头条