Search code examples
model-view-controllercocos2d-iphonekey-value-observing

How to notify parent class from child?


I'm trying to resolves one architectural issue, but I want to find best suitable approach.

I have game scene GameLayer.h which is my view in this case. I have also GameEngine class which I'm trying to be controller. I have my custom Egg class derived from CCNode and some timer logic implemented via schedule in Egg class. I have many Egg object on game scene added via addChild method. So GameEngine.m imports GameLayer.h, and GameLayer.m imports Egg.h

After timer in each Egg runs out, I want to be notified, i.e run some actions, increase score etc. Question is what is the best way to implement such situation. Also I want to obey MVC rule Quick solutions which comes in my mind are

  1. Include Gamelayer.h in Egg class and call some update method in it. Update view (self) and notify GameEngine to save new score.
  2. Include Gamelayer.h in Egg class and call some update method in it. In update method call another update method which is now in GameEngine.h and now from GameEngine save score, and update Gamelayer (the view)
  3. Implement KVO. Problem is that I never done it before, I don't know observer should be GameLayer or GameEngine

Please help, any examples are appreciated


Solution

  • More options:

    1. Use NSNotificationCenter. Your Eggs will post notifications, and your GameLayer will observe.

    2. Use a protocol. Example:

    // in Egg.h
    
    @class Egg;
    @protocol EggDelegate
    // an example method
    -(void)egg:(Egg *)egg hadSomethingHappen:(int)parameter;
    @end
    
    @interface Egg: CCNode
    @property (weak) id<EggDelegate> delegate;
    @end
    
    // in Egg.m
    /// something happened and delegate has to be notified?
    [self.delegate egg:self hadSomethingHappen:someNumber];
    

    Then declare GameLayer to support this protocol:

    @interface GameLayer : CCLayer <EggDelegate>
    

    implement protocol's methods in GameLayer and make it delegate of your Egg objects:

    // somewhere in GameLayer
    Egg *egg = [Egg node];
    egg.delegate = self;
    
    ...
    
    //protocol implementation
    -(void)egg:(Egg *)egg hadSomethingHappen:(int)parameter
    {
    // do something
    }