iPhone Cocos2D游戏编程教科书中的循环引用

时间:2012-05-04 09:00:02

标签: objective-c ios cocos2d-iphone static-methods

一个被滥用的话题,但我找不到答案。我正在关注“学习iPhone和iPad cocos2d游戏开发”一书,并且无法真正理解ShootEmUp示例中的方法(1)是否是最好的方法。作者使用GameScene作为子项添加各种对象(例如Ship,InputLayer等)。有争议的方面是,在这些对象中,通过使用静态方法调用GameScene,该方法返回在GameScene的init方法中实例化的GameScene类的静态实例。这对我来说似乎是一个循环引用,根据许多(e.g. see this post)是要避免的。我不确定在游戏编程中是否也是如此,因为这种方法可以在1找到,并且可能有这个原因。

有人能够澄清吗?我不确定是要完全重构我的代码还是保持静态变量方法。

非常感谢你:)!

Source code

2 个答案:

答案 0 :(得分:2)

我猜你在指这个部分:

static GameScene* instanceOfGameScene;
+(GameScene*) sharedGameScene
{
  NSAssert(instanceOfGameScene != nil, @"GameScene instance not yet initialized!");
  return instanceOfGameScene;
}

这不会创建循环引用。有些人可能认为以这种方式构建代码并不是一种很好的做法,但这是一个不同的讨论。

如果此函数(GameScene对象)的返回值在某些GameScene子节点中未被引用为强属性,则可以。

如果您在其中一个孩子中有这样的话,您将获得循环引用的情况:

@property(nonatomic, strong) GameScene *mainScene;
// OR for non-ARC
@property(nonatomic, retain) GameScene *mainScene;

这会使GameScene对象的引用计数保持为0并解除分配。

希望这会有所帮助。

答案 1 :(得分:2)

你在这里看到的是一个半单一模式,它在整个Cocos中被广泛使用,实际上Cocos框架本身完全是基于单个对象构建的(就像许多Apple的UIKit一样)。游戏经常使用单身人士,因为你通常在游戏中有很多中心数据,比如分数,健康,武器等许多你的对象需要一些知识。您通常还有玩家,敌人等对象需要通知应用程序的中央调度他们正在做什么,以便游戏中的其他对象可以做出相应的反应或调整。

这就是许多Cocos游戏使用你在这里展示的技术的原因。如果你了解单例编程的风险,这是不错的做法。基本上,记住这一点:

  • 无论您是使用单例式技术还是使用其他方法调用父级,您实际上都是以同样的方式做同样的事情。最好直接引用中央游戏引擎,而不是依靠方法为你推导它。我建议不要使用[self parent],因为当您首先要确定“谁是父母”时,可能会很难阅读和调试,而单一访问可以让您立即知道您访问的是谁。
  • 孩子不应该保留其父母。您可以引用父级,但不保留。
  • 此处单身方法的替代方法是在孩子中制作指向父母的iVar。但这基本上是相同的想法,因此为了最小化保留周期的风险,访问单例通常更安全。如果您的iVar设置不正确,您可以使用循环引用。您在此处显示的方法是循环引用。

请注意,此特定代码会阻止您使用+(GameScene*) sharedGameScene方法,直到 GameScene初始化之后的。这就是它成为半单身人士的原因。通常,单例中的此方法将足够智能,如果尚未初始化,则初始化自身,以便使用此类方法返回或首先创建然后返回对象。

可能不是Cocos的一个问题,因为你可能会在做其他任何事情之前初始化游戏场景,所以它已经存在。