【问题标题】:Updating UIView subclass when its property (model) changes当其属性(模型)更改时更新 UIView 子类
【发布时间】:2013-04-09 23:52:42
【问题描述】:

我有一个 UIView 子类CustomView,它有一个属性CustomObject *model,还有几个IBOutlet 属性。 CustomObject 有两个属性,NSString *title 和 NSString *imageName。当model 中的任何内容发生变化时,我想要一种简单、可扩展的方式来更新CustomView 的各种网点。我觉得应该有一些使用 KVO 的简单方法来做到这一点,但是由于可以将新对象分配给 model,所以我不能只订阅这些通知。

我可以想到一种方法(我以前使用过)是覆盖- (void)setModel:(CustomObject *)model 以重做我的布局并重新订阅该对象的 KVO 键。这是最合理的解决方案,还是我忽略了一些明显的东西?

【问题讨论】:

  • 我很清楚,您的 VIEW 有自定义对象属性?我认为这将使编码变得比需要的困难得多。通常你希望 ViewController 能够访问模型并且 IT 更新 View
  • 没错。我以这种方式构建它,以便视图清楚地了解它所描绘的模型。也许让视图控制器在视图上分配这些属性会更好。
  • MVC 有很多变体。让视图观察模型的变化并更新自身是许多常见样式之一。

标签: objective-c uiview subclass key-value-observing


【解决方案1】:

让视图拥有对属性的控制违背了 MVC 设计,这虽然可能使事情变得更加困难。我建议您创建一个 ViewController 自定义子类,并让它通过许多不同的方法将信息传递给视图,其中一种是委托/协议分配,另一种是通知。

【讨论】:

    【解决方案2】:

    在我读完你的问题之前,我打算推荐 KVO,所以,在你的问题结束后,我不得不说,是的,这正是 KVO 的用途。但我也同意另一个答案(来自 Pinwheeler)——不是应该进行观察的视图,而是视图控制器。

    但是,如果可能,视图控制器更常见的是同时管理模型和视图。既然两者都管,就不需要观察什么;它知道模型是否因为它改变了模型而改变。

    【讨论】:

      【解决方案3】:

      我通过像这样覆盖setModel: 来处理这个问题:

      - (void)setModel:(Model *)model {
          if (model != _model) {
              [self disconnectFromModel];
              _model = model;
              [self connectToModel];
          }
      }
      

      在dealloc我也打电话给disconnect:

      - (void)dealloc {
          [self disconnectFromModel];
      }
      

      在connect 中,我建立与模型的连接(如果有的话),并在适当的情况下将模型(或模型的某些部分)传递给我的子视图。示例:

      - (void)connectToModel {
          if (_model) {
              // Maybe start KVO...
              [_model addObserver:self forKeyPath:@"name"
                  options:NSKeyValueObservingOptionInitial context:&MyKVOContext];
      
              // Or maybe register for notifications...
              nameNotificationObserver = [[NSNotificationCenter defaultCenter]
                  addObserverForName:ModelNameDidChangeNotification object:_model queue:nil
                  usingBlock:^(NSNotification *note) {
                      [self modelNameDidChange];
                  }];
      
              // Maybe pass part of the model down to a subview...
              [self.addressView setModel:model.address];
          }
      }
      

      在disconnect 中,我只是撤销我在connect 中所做的操作:

      - (void)disconnectFromModel {
          if (_model) {
              [_model removeObserver:self forKeyPath:@"name" context:&MyKVOContext];
      
              [[NSNotificationCenter defaultCenter] removeObserver:nameNotificationObserver];
              nameNotificationObserver = nil;
      
              [self.addressView setModel:nil];
          }
      }
      

      请注意,如果您确实有也观察模型的子视图,则模型的更改发生在两次传递中。首先,整个视图层次结构与旧模型断开连接。然后整个视图层次结构连接到新模型。

      【讨论】:

        猜你喜欢
        • 2018-05-18
        • 1970-01-01
        • 2020-02-21
        • 2021-11-27
        • 2018-03-01
        • 1970-01-01
        • 2011-03-16
        • 1970-01-01
        • 2016-06-27
        相关资源
        最近更新 更多