如何观看Singleton的数据?

时间:2011-11-11 13:41:12

标签: iphone objective-c ios singleton

我已经设置了一个Singleton类。几个视图控制器将从单例中获取其视图的数据。数据会定期更新。

如何设置应用程序以便视图控制器观察单例以查看数据是否有变化...或者如果有与该视图相关的新数据,则单例向视图发送消息?

3 个答案:

答案 0 :(得分:5)

您可以使用NSNotificationCenter在单身人士的数据发生变化时发布通知(例如设置方法)并让任何关联的视图注册以接收通知。

http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nsnotificationcenter_Class/Reference/Reference.html

答案 1 :(得分:1)

使用某些方法创建协议,并将这些侦听器(它们必须实现协议)添加到数组中。如果你在单身内部改变某些东西,只需用这种方法调用所有听众。

例如:

@protocoll SingletonListenerProtocol
- (void)singleton:(Singleton*)singleton didChangeValueX:(NSString*)newValue;  
@end


-------------------

@implementation Singleton
- (void)setValueX:(NSString*)newX {
  valueX = newX;
  for(id<SingletonListenerProtocol> listener in listeners) {
    [listener singleton:self didChangeValueX:newX];
  }
}
@end

答案 2 :(得分:1)

我会使用key-value observing。它是内置的,因此很容易利用。

  1. 如果您的数据源类已经使用了属性,那么您已经完成了设置。以下是一个例子:

    @interface Source : NSObject {}
    @property (nonatomic, retain) NSString *value;
    @end
    
    @implementation Source
    @synthesize value;
    @end
    

    如果没有,您只需要定义几个特别命名的方法来使其工作:

    - (NSDictionary*)someValue;
    - (void)setSomeValue: (NSDictionary*)newValue;
    

    (其中someValue是您的媒体资源的名称,NSDictionary*是其类型.setSomeValue不需要是公共方法。)

    如果计算了一个属性(因此不适合使用它的设置器),你可以像这样手动触发KVO通知:

    [self willChangeValueForKey:@"someValue"];
    // Do work with changes the effective value of someValue
    [self didChangeValueForKey:@"someValue"];
    
  2. 然后,任何对象都可以在密钥更改时订阅通知,如下所示:

    @implementation Observer
    - (id)initWithSource: (Source *)source
    {
        if ([super init]) {
            _source = source;
            [_source addObserver:self forKeyPath:@"value" options:NSKeyValueObservingOptionNew context:NULL];
        }
        return self;
    }
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
        NSLog(@"New value: %@", [change objectForKey:NSKeyValueChangeNewKey]);
    }
    - (void)dealloc
    {
        [_source removeObserver:self forKeyPath:@"value"];
        [super dealloc];
    }
    @end
    

    您的观察者必须实现observeValueForKeyPath:ofObject:change:context:方法,当任何观察到的对象发生变化时,将调用该方法。您可以通过查看ofObject:KeyPath:传递的参数来判断更改的内容。

  3. 更改一些值!以下是该过程如何与这些示例类一起使用:

    Source *source = [Source new];
    [(Observer*)[Observer alloc] initWithSource: source];
    source.value = @"foo";
    

    您将在控制台上看到此消息,由observer

    记录
    New value: foo
  4. Key Value CodingKey Value Observing编程指南相当不错。我还要看一下NSKeyValueObserving protocol reference