ios - KVO 使用现有模型数据加载新 View

标签 ios model-view-controller key-value-observing

我最近开始发现 KVO 可以做什么,我正在重构一些代码,同时节省大量代码。我确实面临一个非常普遍的问题,这让我想知道是否推荐某种模式。

在某些情况下,我加载一个新的 View Controller ,它需要表示来自已初始化模型的数据。在 -viewDidLoad 上我会注册 KVO:

[_model addObserver:self
         forKeyPath:kSomeKey
            options:NSKeyValueObservingOptionNew
            context:(__bridge void *)(_model)];

并在值更改时更改我的界面:

 -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
                        change:(NSDictionary *)change 
                       context:(void *)context
{
if ([keyPath isEqual:kSomeKey] && context == (__bridge void *)(_model)) {

    [self updateSomeInterfaceElement];

}

不幸的是,当我加载新 View 时, View 不会使用模型中的当前值进行更新,这是可以理解的。

-viewDidLoad 中调用 -updateSomeInterfaceElement 是我的最佳选择吗?这看起来没什么大不了的,但是当监听 10-20 个属性时,它看起来效率很低(特别是因为我所有的 -updateSomeInterfaceElement 方法大多只有 1 行,所以不需要使它们成为一个单独的方法)。有什么办法可以避免这个问题,或者有更优雅的解决方案吗?

最佳答案

您想要更改选项以包含 NSKeyValueObservingOptionInitial。这将导致 KVO 在您添加观察者时触发通知,为观察者提供“初始”值。

另外,顺便说一句,如果为您未注册的通知调用 observeValueForKeyPath:...,您应该养成调用 super 的习惯。另外,避免在 KVO 上下文中使用“事件”指针会更加安全(因为如果当前对象被释放, future 的对象可能具有相同的指针。)我通常更喜欢使用这样的模式:

static void * const MyObservationContext = (void*)&MyObservationContext;

- (void)viewDidLoad
{
    // ... other stuff ...
    [self addObserver:self forKeyPath:@"model.someKey" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial context:MyObservationContext];
    // ... other stuff ...
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{
    if (context == MyObservationContext)
    {
        // Do stuff
    }
    else
    {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

关于ios - KVO 使用现有模型数据加载新 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17093948/

相关文章:

objective-c - KVO : Cannot remove an observer

objective-c - 避免嵌套 KVO 键路径中硬编码字符串的最佳方法

cocoa 键值绑定(bind): What are the explanations of the various options for Controller Key?

iphone - iOS6 自动旋转 - UIPageViewController

ios - 当滚动到屏幕外时,UITableView 部分无法正确绘制/EXC_Bad_Access

php - Symfony Restful API - 公开当前登录用户喜欢的虚拟属性

c# - 如何在 ASP NET Core 中发送复选框输入的值而不是 bool 值?

java - Spring MVC。 HTTP 状态 404

ios - 在 Swift 的手势识别器中获取触摸窗口坐标?

ios - 为什么这段代码不会导致无限循环?