多对一关系消息,KVO或NSNotification

时间:2013-05-30 06:34:57

标签: objective-c messaging key-value-observing nsnotificationcenter

有人可以告诉我创建多对一关系消息系统的最佳或实用方法。我是Objective-C的新手,所以如果我作为Obj-C开发人员“应该知道”,请随时指出我在教程/文档方面的正确方向。

目前,我正在开发一款Brick Breaker游戏,以便在Obj-C / Cocos2D / Box2D上学习并获得更好的成绩。我正在尝试在我的BrickMgr类中创建一个内部消息系统,它保存砖块实例(NSMutableArray)。当砖块被销毁时,我想通知我的父母(BrickMgr)砖块的得分值,以便它可以决定如何使用它或将其传达给平视显示器(HUD)。

从我所做的所有谷歌搜索/阅读中,似乎KVO或NSNotificationCenter将成为可行的方式,但我读过的所有例子都是一对多的关系。我想知道我可以做相反的事情并以多对一关系的形式使用它。

例如:在我的Brick类的每个实例中,当砖被破坏时我可以做

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

并在我的BrickManager类中注册我的观察者以收听postNotification

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

请告知。

1 个答案:

答案 0 :(得分:0)

NSNotifications对于多对关系最有用,他们需要通知多个对象有关更改。您的实现看起来不错(例如,您还需要取消注册dealloc内的通知)。

只要它是一对一的关系,你也可以使用委托(因为每个对象 - 砖 - 需要通知1个单个对象)。

你可以拥有例如:

// 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

在另一个班级的某个地方:

// 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];
}