iPhone上的属性更改通知的标准习惯用法

时间:2010-09-15 17:41:54

标签: iphone design-patterns

假设我有一个代表拼图状态的简单对象。这个难题可以解决也可以解决。我有两个参与这个拼图对象的控制器,它们以两种不同的方式直观地表示状态 - 比如开/关开关和红/绿灯。

当拼图的“已解决”属性发生变化时,控制器需要更新其视图以表示当前状态。是否存在标准的通信习惯,状态从拼图对象变为控制器?

我最初的意图是声明一个自定义协议并跟踪拼图对象中的观察者。当solve属性发生更改时,遍历所有观察者并调用协议上的特定方法。这似乎是一个足够普遍的模式,可能有一些内置支持,但我无法找到我在文档中寻找的确切内容。

3 个答案:

答案 0 :(得分:2)

虽然到目前为止这两个答案都集中在NSNotification的使用上,并且这完全有效,但还有另一种方法可以做你想要的内容到Cocoa对象:Key-Value Observing或KVO。它的重量稍微轻一点,“远处的动作”稍微减少一些。我更喜欢在可能的情况下使用它来观察我的数据模型类中的更改。 YMMV。

答案 1 :(得分:1)

如果我理解正确,您可以使用NSNotification来做您想做的事情。在您的拼图类中,您可以使用postNotificationName告诉任何类在拼图改变状态时观察。要将类注册为拼图的观察者,请使用addObserver和removeObserver方法。以下是这三种方法的定义:

-(void) postNotificationName:(NSString *) aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo;
-(void) addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject;
-(void) removeObserver:(id)observer name:(NSString *)aName object:(id)anObject;

以下是一些用于程序的示例代码:

在你的谜题课中,在改变状态的函数中:

[[NSNotificationCenter defaultCenter] postNotificationName:@"puzzleChangedState" object:self userInfo:NULL]
// if you want to send out moreInfo, like other variables, use userInfo with a dictionary object

在您的控制器或视图等中......无论您想要在哪里获得拼图更改状态消息:

//In your constructor or initialization method, register this class with the puzzle class
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handlePuzzleChangedState:) name:@"puzzleChangedState" object:nil];

这会将您的控制器添加到NotificationCenter,当拼图类发布“puzzleChangedState”通知时,您的控制器的handlePuzzleChangedState:方法将被调用。

这是handlePuzzleChangedState:function:

-(void) handlePuzzleChangedState:(NSNotification *) notification
{
    //handle your puzzle state change here
}

如果您需要更多帮助,请访问以下文档: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Notifications/Introduction/introNotifications.html#//apple_ref/doc/uid/10000043i

希望它成功!

答案 2 :(得分:1)

您可以按如下方式使用通知,而不是自定义协议。 在您的控制器中,viewDidLoad将自己注册为观察者

[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(puzzleStateDidChange:)
                                                 name:@"PuzzleStateDidChange" object:nil];

然后实施

- (void)puzzleStateDidChange:(NSNotification *)notification
{

// set your switch and light according to the state notified
puzzleState = notification.object;
...

}

最后添加

[[NSNotificationCenter defaultCenter] removeObserver:self];

dealloc方法取消注册为观察者。

现在您已准备好接收通知并做出相应的反应。缺少的是要添加到拼图对象的代码。每次状态在拼图对象中发生变化时,

使用类似

的内容
[[NSNotificationCenter defaultCenter] postNotificationName:@"PuzzleStateDidChange" object:yourPuzzleState];

通知您的控制器状态更改。