使用 ARC 访问forwardInvocation方法?

发布于 2024-12-11 14:33:21 字数 496 浏览 1 评论 0 原文

我正在编写 OpenStruct 在 Objective-C 中,使用 转发调用:。但是,编译器显然不知道编译时的转发。使用 ARC 编译给我带来了大量警告。

该代码是开源的,可在 Github 上获取,但目前使用 -fno-objc-arc 进行编译。如果有人能看看我如何使 ARC 兼容,我将不胜感激。

I'm writing a clone of OpenStruct in Objective-C, using forwardInvocation:. However, the compiler isn't aware of the forwarding at compile time apparently. Compiling with ARC gives me a ton of warnings.

The code is open source and available on Github, but is currently compiled with -fno-objc-arc. If anyone could take a look at how I could make this ARC compatible, I'd greatly appreciate it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蘸点软妹酱 2024-12-18 14:33:21

我尝试了这段代码:

OpenStruct *myStruct = [[OpenStruct alloc] initWithDictionary:myDictionary];
NSLog(@"%@ says %@", @"Cow",  [myStruct cowSound]);

无论是否使用 ARC、使用 LLVM 3.0 或 LLVM GCC 4.2,我都会收到警告或错误。我认为您误解了forwardInitation:如果仅在您要向其发送消息的类的类别(@interface)中,仍然需要在某种程度上声明该方法。

例如,当您执行以下操作时:

[someObject doSomething];

如果 doSomething 未在任何地方声明,则无论 someObject 类是否实现了forwardInvocation,都将始终至少生成一个警告(“someObject 可能不会响应 doSomething”)。正如您所注意到的,编译器确实不知道转发,并且它也不能依赖您的forwardInvocation 实现来保证消息传递。对于带有或不带有 ARC 的 LLVM 3.0,这可能已更改为生成错误,因为 ARC 的开发目标是避免出现更多编译器错误而不是运行时问题。

现在您仍然可以向未实现方法的对象发送消息。例如,通过使用 Objective-C 运行时方法 objc_msgSend 或通过 NSInitation。但这会导致您计划创建的简单易用的界面失效。

顺便说一句,您的 OpenStruct 使用示例并不能真正证明为什么与 [struct getValueForKey:@"moo"]; 等简单访问器相比,通过消息传递访问动态结构更简单。 …如果您仔细考虑一下,那么 [struct moo] 与第一种方法相比,给用户带来的好处很少或根本没有。 “moo”方法无论哪种方式都是动态的(字符串或转发消息),并且在运行时不会捕获拼写错误。

I tried this code:

OpenStruct *myStruct = [[OpenStruct alloc] initWithDictionary:myDictionary];
NSLog(@"%@ says %@", @"Cow",  [myStruct cowSound]);

I get warnings or errors with and without ARC, with LLVM 3.0 or LLVM GCC 4.2. I think you've misunderstood that forwardInvocation: still requires the method to be declared at some level, if only in a category (@interface) of the class you're sending the message to.

For example, when you do:

[someObject doSomething];

Then this will always generate at least a warning ("someObject may not respond to doSomething") if doSomething is not declared anywhere, regardless of whether the someObject class implements forwardInvocation or not. Like you noticed, the compiler is indeed not aware of the forwarding, and it also can't rely that your implementation of forwardInvocation guarantees message delivery. With LLVM 3.0 with or without ARC this may have been changed to generate an error instead, because ARC's development goal was to err on the side of more compiler errors rather than runtime issues.

Now you can still send messages to an object that doesn't implement a method. For example by using Objective-C runtime method objc_msgSend or via NSInvocation. But that voids the simple to use interface that you were planning to create.

Btw, your usage example for OpenStruct does not really justify why it is any simpler to access the dynamic struct via messaging compared to simple accessors like [struct getValueForKey:@"moo"]; … if you think this over then [struct moo] gives users little or no benefit over the first approach. The "moo" method is dynamic either way (a string or forwarded message) and a typo won't be caught at runtime.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文