3

我一直在尝试使用 Objective-C 来实现一个简单的基于组件的游戏对象架构,这与Mick West的文章“Evolve Your Hierarchy”很相似。为此,我成功地使用了 Mike Ash 的文章'Objective-C Message Forwarding'中概述的一些想法,即使用该-(id)forwardingTargetForSelector:方法。

基本设置是我有一个容器 GameObject 类,它包含组件类的三个实例作为实例变量:GCPositioning、GCRigidBody 和 GCRendering。该-(id)forwardingTargetForSelector:方法返回使用该方法确定的将响应相关选择器的任何组件-(BOOL)respondsToSelector:

所有这一切,在某种程度上,就像一个魅力:我可以在 GameObject 实例上调用一个方法,该方法的实现在其中一个组件中找到,并且它可以工作。当然,问题在于编译器在每次调用时都会给出“可能无法响应……”警告。现在,我的问题是,我该如何避免这种情况?具体来说,关键是每个 GameObject 实例都会有一组不同的组件?也许是一种在每个对象的基础上向容器对象注册方法的方法?例如,我可以创建某种-(void)registerMethodWithGameObject:方法,我该怎么做?

现在,很明显我对 Cocoa 和 Objective-C 还很陌生,而且基本上只是在闲逛,这整个事情在这里可能非常陌生。当然,虽然我非常想知道我的具体问题的解决方案,但任何愿意解释更优雅的方法的人也将受到欢迎。

非常感谢,-巴斯蒂安

4

5 回答 5

2

我不认为发送容器对象的所有组件消息是 Mick West 所建议的——这无助于消除“单片游戏实体对象”的想法。

最终目标是让组件直接相互通信,根本没有容器对象。在此之前,容器对象充当期望每个游戏实体有一个对象的旧代码和新的组件到组件系统之间的粘合剂。

也就是说,您根本不需要在最终产品中使用消息转发,因此忽略警告,或者像id现在这样声明变量以使它们安静下来,并不是那么难看。(文章中列出的计划是最终删除导致警告的代码!)

于 2010-04-15T00:43:23.590 回答
0

您可以使用 id 类型 - 或者您可以使用 performSelector 方法调用方法,或者如果参数很复杂,则创建一个 NSInvocation 。然而,这只是绕过编译器警告的一种方式。如果您的对象响应几种方法,那么可能声明一个协议可能会有所帮助,尽管同样的警告也适用。

于 2010-04-14T21:16:37.150 回答
0

让这些警告消失的一个简单方法是声明类型的实例变量id

这样,编译器就假定您知道您正在对对象的类型做什么,并且该对象将响应您发送给它的任何消息,或者如果您不关心它。

于 2010-04-14T20:10:36.447 回答
0

覆盖你的游戏对象的-respondsToSelector:方法。你的实现应该反过来向respondsToSelector:它的每个实例发送一条消息,YES如果其中任何一个返回,则返回YES

于 2010-04-14T20:50:20.827 回答
0

如果我正确理解问题,另一个选择是实施协议。这是链接java中的接口,变量可以这样声明:

id anObjectRef

这样编译器就知道 anObjectRef 引用的对象符合协议。

还有一些方法可以在您强制转换或分配之前告诉您特定对象是否符合特定协议。

于 2010-04-15T00:56:16.637 回答