基于Obj-C组件的游戏架构和消息转发

时间:2010-04-14 20:04:28

标签: objective-c architecture message forwarding

我一直在尝试使用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相当新鲜,而且基本上只是在身边,这整件事情在这里可能非常陌生。当然,虽然我非常想知道我的具体问题的解决方案,但是任何愿意解释更优雅的方式的人都会非常受欢迎。

非常感谢,-Bastiaan

5 个答案:

答案 0 :(得分:2)

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

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

也就是说,你不应该在最终产品中使用消息转发,所以忽略警告,或者现在将变量声明为id来安静它们,并不是那么难看。 (该文章规定的计划是最终删除导致警告的代码!)

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

覆盖GameObject的-respondsToSelector:方法。您的实现应该依次向其每个实例发送respondsToSelector:消息,如果其中任何一个返回YES,则返回YES

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

id anObjectRef

这样编译器就会理解anObjectRef引用的对象符合协议。

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