【问题标题】:Swift: notify delegate in didSet?Swift:在 didSet 中通知委托?
【发布时间】:2017-11-08 02:09:42
【问题描述】:

我需要一些关于在 Swift 中通知委托的最佳实践的帮助,我有一个 ScoreStats 模型,它有一个 Student 列表,每个 Student 都有一个分数,并且该模型提供了所有 @ 的平均分数987654324@指的是:

class ScoreStats {

  private(set) var averageScore: Double = 0

  var student: [Student]? {
    if let students = students {
      // calculate `averageScore`
    }
    // notify delegate
    self.delegate.averageScoreUpdated()
  }
}

我的问题是,来自 Objective C,人们通常有这样的方法:

- (void)updateStudents:(NSArray<Student *> *)students {
  self.students = students;
  // calculate `averageScore`
  [self.delegate averageScoreUpdated];
}

从特定语言的角度来看,我可以使用didSet 达到相同的目的,但在其他方面有什么问题吗?例如,在 Swift 中公开 students 属性意味着不同的地方都可以修改它并且代理会收到通知,而且编码人员不清楚设置students 属性会触发averageScore 的代理通知,而有ObjC 中的专用方法使其更加清晰。

意见?

【问题讨论】:

    标签: objective-c swift delegates


    【解决方案1】:

    您的问题并不是特定于语言的。您需要决定何时应调用委托。在您的 Objective-C 代码中,您添加了一个 updateStudents 方法。但是由于某种原因,您在 Swift 代码中采用了完全不同的方法。为什么?

    在任何一种语言中,您都可以选择将students 属性设为完全公开、完全私有或公开只读且可私有设置。当然,Swift 增加了其他级别的可见性,但这与本次讨论无关。

    在任何一种语言中,您都可以选择在其他方法(如 updateStudents)或属性的 setter 中调用委托(同样,Swift 为此添加了更精细的选项,但这并不重要)。

    所以你的问题的基础是有缺陷的。它不是特定于语言的。首先决定何时调用代理。是在任何时候更新students 属性还是在调用其他方法时?

    如果您希望您的 Swift 代码像您的 Objective-C 代码一样工作(具有相同的语义),您不想在属性的 didSet 中调用委托。您要添加 updateStudents 方法。并确保您使students 属性在两种语言中具有相同的可见性。

    【讨论】:

    • 您好,感谢您的详细回答!我仍然认为它是特定于语言的,Swift 有办法在通过didSet 设置属性后做某事,ObjC 不会免费提供此功能,但可以肯定的是,您可以使用观察者实现相同的目的。我的问题应该重新表述,考虑到 ObjC 代码,如果我想将它转换为 Swift,如果我通过 studentsdidSet 通知委托,除了有一个专用方法来更改 students 之外,还有什么问题吗? .
    • 在 Objective-C 中你可以重写“setter”方法。如果你在studentsdidSet 中调用delegate,那么你的Swift 代码与你的Objective-C 代码完全不同。这是我回答的很大一部分。这不是“错误”,只是完全不同。如果这就是你想要的,那很好。
    • 谢谢,是的,我忘记了 setter 覆盖!
    猜你喜欢
    • 1970-01-01
    • 2019-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多