gpt4 book ai didi

objective-c - Objective C 运行时如何查找已定义的消息?

转载 作者:行者123 更新时间:2023-12-03 17:30:16 25 4
gpt4 key购买 nike

我是 Objective C 的新手,并且有 C/C++ 背景,我正在努力理解 Objective C 有多少动态

Programming withObjective-C Page 38

考虑以下代码:

id someObject = @"Hello, World!";
[someObject removeAllObjects];

在这种情况下,someObject将指向一个NSString实例,但编译器除了知道它是某种对象之外,对该实例一无所知。 removeAllObjects 消息是由一些 Cocoa 或 Cocoa Touch 对象(例如 NSMutableArray)定义的,因此编译器不会提示,即使此代码会在运行时生成异常,因为NSString 对象无法响应removeAllObjects。

removeAllObjects 消息是由某些 Cocoa 或 Cocoa Touch 对象(例如 NSMutableArray)定义的,因此编译器不会提示

这是否意味着运行时实际上会查找所有已实现的方法?如果是的话,不影响性能吗?

如果我的理解有误,请指出。

谢谢。

最佳答案

TheEye 的答案是完全错误的,我认为对于那些刚接触 Objective-C 的人来说了解它的实际工作原理非常重要。

Objective-C 中没有方法。您向对象发送消息。这不仅仅是一个微小的语法差异,更是一种根本不同的哲学。

当您向对象发送 removeAllObjects 消息时(无论它是声明为 id 还是 NSString*),实际发生的情况是,运行时会查看该对象的 isa (is-a) 指针运行时,它指向该对象的定义。

每个对象定义都有一个该对象实现的消息选择器列表。为了运行时性能,系统缓存选择器。因此它将检查缓存是否已包含该选择器。如果是,运行时会跳转到该位置并开始执行在那里找到的代码。它还将检查继承类链,看看它们中是否有任何一个实现了该消息。

如果找不到消息,则会将选择器发送到forwardInitation:所有未知消息都会发生这种情况。碰巧 NSObject 的 forwardInspiration: 的默认实现调用 doesNotRecognizeSelector: ,这会崩溃。

您可以通过在自己的类上实现 forwardInitation: 来自行测试这一点,并且不执行任何操作。然后尝试将随机选择器发送到您的类的实例。您将看到没有出现任何错误。这允许您创建代理对象来检查、过滤或修改发往另一个对象的消息。您还可以完全模拟不同的类别。

代码中声明的变量类型只是一个提示,因此编译器可以帮助您在编译时捕获错误。在运行时,这并不重要。 Objective-C 仅查看 isa 指针来确定对象的类,从而确定它支持哪些消息选择器。

这也是为什么你可以在运行时重写一个类,向类添加新方法等。你甚至可以在运行时通过更改isa指针来更改对象的类型,这将导致该对象的字节被重新定义。解释为新类型(警告:这是高级内容,所以请小心!)

关于objective-c - Objective C 运行时如何查找已定义的消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23006781/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com