0

假设我有两个UIViewController被调用的子类MasterViewControllerDetailViewController

DetailViewController有一个类型NSNumber为 calledlevel和一个UILabelcalled的属性levelLabel

MasterViewController有一个DetailViewControllerToDetail. MasterViewController的 prepareForSegue 是这样的

    - (void)prepareForSegue:(UIStoryboardSegue)segue sender:(id)sender
    {
       if ([segue.identifier isEqualToString:@"ToDetail"]) {
         DetailViewController *detailVC = (DetailViewController *)segue.destinationViewController;
         detailVC.level = [NSNumber numberWithInt:10]; // never mind the literal...pretend there was some algorithm for it
       }
     }

那么,在DetailViewController我们实现 levelLabel 的 setter 时,如下所示:

     - (void)setLevelLabel:(UILabel *)levelLabel
     {
       if (levelLabel) {
         _levelLabel = levelLabel;
         _levelLabel.text = level.stringValue;
       }
     }

这是好的代码设计吗?另外,你能批评一下我的代码编写风格吗?我几乎是在运行中编写了所有这些代码,所以这几乎就是我编写代码的大部分方式。

我在洗澡的时候想到了这个问题,因为这是我实现几乎所有依赖于 segue 的标签文本的设置的方式。

4

1 回答 1

2

以下是我自己对这种关系的思考方式。斜体适用于您的问题。

你有被控制的东西(标签)控制器(目标视图控制器)和它被控制的上下文(源视图控制器)。这也可以表示为模型-视图-控制器,但我认为考虑上下文可以适用于更具体和本地化的情况。

您通常应该尝试使信息流向一个方向,从上下文向下。对象不应该知道它们存在的上下文,即它们不应该要求任何信息,它们应该被告知它们需要操作的一切。所以源视图控制器应该将级别推送到目标视图控制器,目标视图控制器应该将此信息推送到标签。这是你已经拥有的,有点。

以上述为基础,不仅信息应该在一个方向流动,而且我还尝试确保关系是因果关系,即将信息从一个对象推送到另一个对象应该导致它随后被推送到下一个对象。您的代码没有这样做,这可能就是您对此感觉不好的原因。

更合适的做法是在关卡设置器中设置标签的文本属性,这样当您设置或更改关卡时,标签会随之更新。标签可能已加载,也可能未加载,因此您必须检查它是否正在使用-isViewLoaded-viewDidLoad是在首次加载时设置 text 属性的合适位置。

(当我说“推送”时,这只是我考虑设置属性或传递参数的方式,因为它暗示了方向性。它实际上是依赖注入。拉取信息的一个例子是委托和数据源。但请注意这里的对象仍然是“在不知道任何上下文的情况下,委托和数据源被明确定义为协议,而不是类,并且通常在同一个头文件中,并且它们自己从周围的上下文中推送到对象上。所以是的,对象正在请求信息,但是它自己的术语和它不知道的系统。)

重新编码风格:

这正是我编写代码的方式,但请注意 Apple保留使用下划线前缀

于 2012-07-20T12:47:27.850 回答