使用 ARC 访问forwardInvocation方法?
我正在编写 OpenStruct 在 Objective-C 中,使用 转发调用:。但是,编译器显然不知道编译时的转发。使用 ARC 编译给我带来了大量警告。
该代码是开源的,可在 Github 上获取,但目前使用 -fno-objc-arc 进行编译。如果有人能看看我如何使 ARC 兼容,我将不胜感激。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我尝试了这段代码:
无论是否使用 ARC、使用 LLVM 3.0 或 LLVM GCC 4.2,我都会收到警告或错误。我认为您误解了forwardInitation:如果仅在您要向其发送消息的类的类别(@interface)中,仍然需要在某种程度上声明该方法。
例如,当您执行以下操作时:
如果 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:
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:
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.