0

Could someone please advise me on best or practical way of creating a many to one relationship messaging system. I am new to Objective-C so if this something that I "should know" as an Obj-C developer, please feel free to point me in the right direction on tutorials/documentation.

Currently, I'm working on a Brick Breaker game to learn and get better at Obj-C/Cocos2D/Box2D. I am trying to create an internal messaging system in my BrickMgr class that holds instances of bricks (NSMutableArray). When a brick is destroyed, I want to notify my parent(BrickMgr) the score value of the brick, so that it can then decide how to use or communicate it to the heads-up-display(HUD).

From all the Googling/reading I've done, it seems like KVO or NSNotificationCenter would be the way to go, but all the examples I've read are one-to-many relationship. I am wondering could I do the opposite and use it in the form of many-to-1 relationship.

E.g.: In each instance of my Brick class, when the brick is destroyed I can do

//Brick class, when brick.state = BRICK_DESTROYED
[NSNotificationCenter defaultCenter] postNotificationName:BB_SCORE_CHANGED_NOTIFICATION object:self userInfo:nil];

and in my BrickManager class register my observer to listen to the postNotification

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onScoreChanged:) name:BB_SCORE_CHANGED_NOTIFICATION object:nil];

Please advise.

badboy11
  • 541
  • 1
  • 6
  • 19

1 Answers1

0

NSNotifications are most useful for to-many relations, where they need to notify multiple objects of a change. Your implementation looks good (you'll also need to unregister for the notification inside dealloc for instance).

As long as it's a to-one relation, you can also use delegates (since each object - brick - will need to notify 1 single object).

You could have for instance:

// Brick.h
@class Brick;

@protocol BrickDelegate <NSObject>
-(void)brickStateChanged:(Brick *)sender;
// .. some other methods
@end

@interface Brick : NSObject {
    id<BrickDelegate>    _delegate;
}

@property(nonatomic, assign) id<BrickDelegate>    delegate;
@end

// Brick.m
@implementation Brick
@synthesize delegate=_delegate;

...

-(void)setState:(int)newState{
    if(_state==newState) {
        return;
    }
    _state=newState;
    [self.delegate brickStateChanged:self];
}

...
@end

Somewhere in another class:

// in the init method for instance
_bricks = [[NSMutableArray alloc] init];
Brick *b = [[Brick alloc] init];
b.delegate = self;
[_brocks addObject:[b autorelease]];

-(void)brickStateChanged:(Brick *)sender {
    // handle state changed for the brick object
}

-(void)dealloc{
    // reset the delegates - just in case the Brick objects were retained by some other object as well
    [_bricks enumerateObjectsUsingBlock:^(Brick *b, NSUInteger idx, BOOL *stop){
        b.delegate = nil;
    }];
    [_bricks release];
    [super dealloc];
}
alex-i
  • 5,406
  • 2
  • 36
  • 56
  • You sir have given me the ideal soln of my choice. I just learnt about delegates last wk & it's awesome. Protocol makes sure one set of method calls are used, & it's self documenting. Due to my newbie status, I have not started thinking creative ways to use delegates like above. I was stuck in the mindset that only 1 instance of each class type had to exist in order to implement delegates. You have opened my eyes and broadened my learning. Now I can also trigger when to remove a destroyed brick. – badboy11 May 30 '13 at 09:24