gpt4 book ai didi

Objective-C:performSelector:与 forwardInvocation:

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:19:29 28 4
gpt4 key购买 nike

对 objective-c 很陌生,但我遇到了一种似乎很常见的情况:我希望 ClassA 要求 ClassB 在只有 ClassB 知道的对象上执行一个方法(并且还使用了一个方法是A 级不知道)。

我找到了两种方法:performSelector:forwardInvocation: - 但我想了解更多并加深对每种方法的理解。我在苹果开发者文档中找到了这条注释:

The aSelector argument [in performSelector:] should identify a method that takes no arguments. For methods that return anything other than an object, use NSInvocation.

..这是否意味着以 - (id)methodName 开头的方法将使用 performSelector:,而说 - (int)nonObjectMethodName 会使用 forwardInvocation:?

返回 (void) 的方法又如何呢?或返回非 id 对象的方法,例如(NSString)?

最佳答案

没有。 -forwardInvocation: 用作消息转发机制的一部分。不要担心消息转发,因为它实际上只被代理对象使用,而且你永远不需要使用它并且知道你正在使用它的可能性很大。

-performSelector: 假定消息的返回类型是 id 或兼容的,因此如果它用于发送返回类型不同的消息(例如比指针更宽,例如 32 位系统上的 long long,或者通过不同的寄存器/地址返回,例如 float 或大型 struct.)

如果你想间接发送这样的消息,你可以创建 NSInvocation 类的实例,然后发送它 -invoke .然后将返回值存储在调用对象中,并可以通过它访问。 -forwardInvocation: 在这种情况下您永远不会使用。

一般来说,如果您发现自己在使用 -performSelector:,您可能正在处理反模式。在这种情况下,您正试图发送一条 ClassA 并不知道的消息。替代解决方案是公开这些私有(private)方法。


如果您同时拥有 ClassAClassB,您可以为 ClassB 创建一个包含您想要的私有(private)方法的“私有(private)” header 采用。如果其他人(例如 Apple)拥有 ClassB,您正在处理未记录的 API,并且可能需要寻找另一种方法,因为 Apple 将拒绝使用此类 API 的应用。

要创建私有(private) header ,请进入 Xcode 并创建一个新的 header 文件。将其命名为“ClassB+Internal.h”或“ClassB+PrivateMethodsForMeOnly.h”。将其视为您的项目的私有(private)文件——除非他们与 ClassB 是对等的(相同的子项目或库或组件),否则没有人可以使用它。在这个新标题中,添加以下内容:

#import "ClassB.h" // so we get the original class definition

@interface ClassB (PrivateMethodsForMeOnly)
- (double)someMethod;
- (const struct low_level_c_type_t)otherMethod:(int)i;
// etc. etc. etc.
@end

并且在 ClassA.m 中(不是 ClassA.h 除非你想将这些方法公开给所有使用 ClassA< 的人!) 在您的包含部分中添加以下行:

#import "ClassB+PrivateMethodsForMeOnly.h"

ClassA 此后将可以访问新类别中的那些方法。

关于Objective-C:performSelector:与 forwardInvocation:,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11379525/

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