Circular references in iPhone Cocos2D game programming textbook

◇◆丶佛笑我妖孽 提交于 2019-12-11 11:05:09

问题


an abused topic but I couldn't find an answer to this. I am following the "Learn iPhone and iPad cocos2d Game Development" book and cannot really understand if the approach in the ShootEmUp example (available at 1) is the best one. The author uses a GameScene to which adds as child various objects (e.g. Ship, InputLayer etc..). The controversial aspect is that within those object there are calls to the GameScene via using a static method that returns a static instance of the GameScene class that is instantiated in the init method of GameScene. This to me seems a circular reference and according to many (e.g. see this post) is something to avoid. I am not quiet sure if that's also true in Game Programming as this approach is found in 1 and there might be a reason for this.

Would anyone be able to clarify? I am undecided whether to restructure my code completely or keep the static variable approach.

Thank you very much :)!

Source code


回答1:


What you see here is a semi-singleton pattern, and it is used extensively throughout Cocos, in fact the Cocos framework itself is built entirely on singleton objects (as is a lot of Apple's UIKit). Games frequently employ singletons because you typically have a lot of central data in a game, like scores, health, weapons, etc that many of your objects need some knowledge of. You also typically have objects, like players, enemies, etc that need to notify the central dispatch of your app what they are doing so other objects in the game can react or adjust accordingly.

This is why many Cocos games use the technique you've shown here. It is not bad practice if you understand the risks of singleton programming. Basically, keep this in mind:

  • Whether you use a singleton-style technique or instead call up the parent using another method, you are essentially doing the same thing either way. It's probably better to directly reference the central game engine directly than rely on methods to derive it for you. I would not recommend using [self parent] as that can get hard to read and debug later when you first have to figure "who is the parent," instead a singleton access lets you know immediately who you are accessing.
  • A child should never retain its parent. You can reference the parent, but don't retain.
  • An alternative to the singleton approach here is to make an iVar in the child that points to the parent. But this is essentially the same idea, so to minimize the risks of a retain cycle, accessing the singleton is typically safer. If your iVar is not set properly, you could have a circular reference. The method you've shown here is not a circular reference.

Note that this particular code prevents you from using +(GameScene*) sharedGameScene method until after the GameScene has been initialized. This is what makes it a semi-singleton. Typically, this method in a singleton will be smart enough to initialize itself if it is not already initialized so that using this class method either returns or first creates and then returns the object.

Probably not an issue in Cocos since you will likely initialize the Game Scene before you do anything else, so it will already exist.




回答2:


I'm guessing you're referring this part :

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

This doesn't create a circular reference. Some might argue that's not a great practice to build your code this way, but that's a different discussion.

If the returning value from this function (the GameScene object) isn't referenced as strong property in some of GameScene children, it's ok.

You would have the case of circular reference if you had this in one of the children :

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

These would have kept the reference count for the GameScene object from getting to 0 and dealloc-ing.

Hope this helps.



来源:https://stackoverflow.com/questions/10445790/circular-references-in-iphone-cocos2d-game-programming-textbook

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!