是否可以将数据作为NSNotifications的一部分传递?

时间:2012-02-29 14:56:42

标签: objective-c ios model-view-controller

场景,在纸牌游戏的背景下:

用户在屏幕上移动卡片。作为移动的结果,卡的坐标改变。如果发现卡片位于某个特定位置,我们希望确保更新卡片对象(模型)以包含这些坐标。

但是View不应该直接与模型交谈..所以

View不会直接更新卡,而是通知其控制器“卡已落地”。收到此通知后,我希望控制器更新卡的位置而不是视图(控制器更新模型)

问题1: 我正确地考虑这种情况吗?

问题2: 是否可以将数据与通知一起发送到控制器?

3 个答案:

答案 0 :(得分:2)

这就是userInfo词典和object NSNotification的用法。在这种情况下,它是您想要的object。例如:

// In your model header file

extern NSString * const CardMovedNotification;

// In your model implementation file

NSString * const CardMovedNotification = @"CardMoved";

...

[[NSNotificationCenter defaultCenter] postNotificationName:CardMovedNotification object:theCardThatMoved];

然后您的观察者可以通过[notification object]获取该卡。如果您需要传递更多信息,则需要创建一个字典并通过userInfo将其传递为postNotificationName:object:userInfo:。然后观察者可以通过[notification userInfo]查询它。

答案 1 :(得分:2)

您的方案不需要NSNotifications:基于代理的简单方法应该这样做。

视图应定义委托接口,并提供非保留delegate属性。控制器应实现委托接口,并将其自身设置为视图的委托。然后,视图将通知其代理人,甚至不知道它通知控制器。然后控制器将通知传递给模型。

@protocol CardDelegate
-(void)cardHasLanded:(SOCard*)card atPosition:(SOPosition*)pos;
@end

@interface MyView
@property (weak, nonatomic,readwrite) id<CardDelegate> delegate;
@end

@implementation MyViewController
-(id)init { // This should be in your designated initializer
    self = [super init];
    if (self) {
        MyView *view = [[MyView alloc] init];
        view.delegate = self;
        self.view = view;
    }
    return self;
}
-(void)cardHasLanded:(SOCard*)card atPosition:(SOPosition*)pos {
    // Update the model
}
@end

@implementation MyView
@synthesize delegate;
-(void) doSomething {
    // ...
    if (cardHasLanded) {
        [delegate cardHasLanded:card atPosition:pos];
    }
    // ... more code
}
@end

答案 2 :(得分:0)

我同意不需要通知。通常对于UI对象坐标,我不会使用模型对象,因为坐标耦合到UI对象(或者你将在哪里绘制它?)。您需要做的是将控制器注册到传递触摸的UI对象中的触摸结束事件,并更新(在响应控制器方法中)对象的坐标(如果它们确实在所需位置内)。 (与按钮和其他UI对象一样)