【问题标题】:Many to one relationship messaging, KVO or NSNotification多对一关系消息传递,KVO 或 NSNotification
【发布时间】:2013-05-30 06:34:56
【问题描述】:

有人可以就创建多对一关系消息传递系统的最佳或实用方法向我提供建议。我是 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];

请指教。

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • 您先生给了我我选择的理想解决方案。我上周刚刚了解了代表,这太棒了。协议确保使用一组方法调用,并且它是自我记录的。由于我的新手身份,我还没有开始思考像上面那样使用代表的创造性方法。我陷入了这样一种心态,即每个类类型只有一个实例才能实现委托。你打开了我的眼界,拓宽了我的学习。现在我还可以触发何时移除被破坏的砖块。
    猜你喜欢
    • 1970-01-01
    • 2012-01-10
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2018-06-15
    • 1970-01-01
    • 2021-04-01
    相关资源
    最近更新 更多