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

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

任何人都可以澄清? 我不确定是完全重构我的代码还是保持静态variables方法。

非常感谢你 :)!

源代码

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

这就是为什么许多科考游戏使用你在这里显示的技术。 如果你了解单体编程的风险,这是不错的做法。 基本上,记住这一点:

  • 无论您使用单例风格的技术,还是使用其他方法调用父项,您本质上都在做同样的事情。 直接引用中央游戏引擎比直接引用方法更好。 我不会推荐使用[self parent]因为在第一次需要确定“谁是父母”时,以后可能难以阅读和debugging,而是通过单例访问让您立即知道您正在访问的是谁。
  • 小孩不应该保留父母。 您可以引用父级,但不保留。
  • 这里的单例方法的替代方法是在指向父代的子代中创build一个iVar。 但是,这基本上是相同的想法,所以为了最小化保留周期的风险,访问单例通常是更安全的。 如果你的iVar设置不正确,你可以有一个循环引用。 你在这里显示的方法不是循环引用。

请注意,这个特殊的代码会阻止你在GameScene初始化之前使用+(GameScene*) sharedGameScene方法。 这是什么使它成为一个半单身人士。 通常情况下,这个方法在单例中是非常聪明的,如果它还没有被初始化,就可以初始化,这样使用这个方法返回或者先创build并返回对象。

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

我猜你是指这部分:

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

这不会创build循环引用。 有人可能会认为这样做并不是很好的做法,但这是一个不同的讨论。

如果这个函数( GameScene对象)的返回值没有作为一些GameScene子元素的强属性引用,那就没问题。

如果您在其中一个孩子身上有这样的情况,您将会有循环引用的情况:

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

这些将保持GameScene对象的引用计数变为0并释放。

希望这可以帮助。