【问题标题】:Key Value Observe static NSDictionary on facade class键值观察门面类上的静态 NSDictionary
【发布时间】:2015-01-10 15:20:51
【问题描述】:

我有一个ServiceFacade 类,其中包含用于与后端服务通信的类方法。 在那个ServiceFacade 类上,我有一个返回NSMutableDictionary 的静态方法,我在其中保持当前ServiceFacade 的下载操作。 我想在AppDelegate 或任何其他地方观察NSMutableDictionary 的变化。应用委托似乎没有响应

- (void)addObserver:(NSObject *)anObserver
     forKeyPath:(NSString *)keyPath
        options:(NSKeyValueObservingOptions)options
        context:(void *)context{

}

返回NSMutableDictionary的方法:

    +(NSMutableDictionary *)downloadOperations
{
    if (_downloadOperations)
    {
        return _downloadOperations;
    }
    [_downloadOperations addObserver:[AppDelegate sharedAppDelegate] forKeyPath:@"downloadOperationsDict" options:0 context:NULL];
    _downloadOperations = [NSMutableDictionary dictionary];
    return _downloadOperations;
}

有什么想法吗?

【问题讨论】:

  • KVO 只有在_downloadOperations 指针改变时才会被触发。改变_downloadOperations 指向的字典内容将不会触发 KVO 通知。
  • 不,只有在-setDownloadOperation被执行时才会触发。这就是问题所在。
  • 是的。抱歉,这就是我的暗示,但解释得很糟糕。

标签: ios objective-c observer-pattern nsmutabledictionary key-value-observing


【解决方案1】:

无法观察NSMutableDictionary 的变化。但是有两种解决方法

1) 继承 NSMutableDictionary 并在 setObject:forKeyremoveObjectForKey 上触发通知。
2)包装您的 _downloadOperations 写入/删除操作并在那里触发通知。

我建议您使用 2) 变体,因为子类化 NSMutableDictionary 并不容易。

所以 2) 变体将是这样的。
将这2个方法添加到ServiceFacade类中

- (void)setDownloadObject:(id)aObj forKey:(id<NSCopying>)aKey
{
     [self.downloadOperations setObject:aObj forKey:aKey];
     [[NSNotificationCenter defaultCenter] postNotificationName:@"DownloadOperationsChanged" object:self
                                                           userInfo:self.downloadOperations];
}

- (id)removeDownloadObjectForKey:(id<NSCopying>)aKey
{
     [[self.downloadOperations] removeObjectForKey:aKey];
     [[NSNotificationCenter defaultCenter] postNotificationName:@"DownloadOperationsChanged" object:self
                                                           userInfo:self.downloadOperations];
}

在此之后,您需要通过这 2 种方法从该字典中添加和删除对象。您还可以订阅更改

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(downloadOperationsChanged:)
                                                 name:@"DownloadOperationsChanged"
                                               object:nil];
    return YES;
}

- (void)downloadOperationsChanged:(NSNotification *)aNotification
{
    NSLog(@"Operations : %@", aNotification);
}

【讨论】:

  • 这是我的备份解决方案。谢谢你的回答!
猜你喜欢
  • 2016-11-09
  • 2017-03-01
  • 2011-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-25
  • 1970-01-01
相关资源
最近更新 更多