【问题标题】:Does a class being its own delegate follow iOS convention?作为自己的代表的类是否遵循 iOS 约定?
【发布时间】:2015-05-17 06:07:58
【问题描述】:

抱歉,这个问题可能听起来“主观”,但我认为它应该有一个非常明确的答案。我有一个类“LocationManager”,我想管理我的核心位置逻辑。我有两个选择:

  1. LocationManager 具有引用 CLLocationManager 实例的强属性。 LocationManager 是 CLLocationManager 的委托,并从它那里接收位置更新。

  2. LocationManager 是 CLLocationManager 的子类,并表示 self.delegate = self 以便它可以接收自己的位置更新。

我很好奇这些选项中的哪一个被认为是“正确”的事情,我确信必须有一个首选的方式。谢谢!

【问题讨论】:

    标签: ios objective-c core-location


    【解决方案1】:

    不应将CLLocationManager 子类化并将其委托设置为self,因为它违反了CLLocationManager 的合同。由于当前定义了该类,它具有delegate 属性。此属性用作合同,规定您可以将此属性设置为其他对象,并且此对象将接收委托通知。如果您将CLLocationManager 子类化(我们称之为MyLocationManager),并且如果对象的delegate 属性指向它自己,那么您很可能会造成MyLocationManager 仅在用户执行 时才按承诺工作的情况不要delegate 属性用于他自己的目的。从用户的角度来看,MyLocationManager 是一个没有可用的delegate 属性的CLLocationManager。这违反了Liskovs Substitution Principle,顺便说一句。这里要问的问题是:如果某些ViewController 类决定使用它并使其delegate 属性指向自身(ViewController),MyLocationManager 是否仍然有效?

    此外,如果您说self.delegate = self,它不再是“委托”。所以我会说最好使用变体 1。

    感谢您的提问。

    【讨论】:

      【解决方案2】:

      第一个选项对我来说似乎是正确的,因为继承 CLLocationManager (#2) 没有多大意义。您将为其添加什么功能?如果你没有添加任何东西,为什么要子类化?

      您所关心的只是封装有关位置更新的消息。我想说您在第一种情况下可以接受地使用委托/协议模式。

      Jef 是对的,有时可以将另一个类的子类设置为其自己的委托。尽管您需要注意该对象如何响应某些消息。

      【讨论】:

        【解决方案3】:

        是的,您可以毫无问题地做到这一点。我有一个 UITextField 的子类,它是它自己的委托。

        【讨论】:

        • 你可以,但你不应该。它彻底颠覆了整个委托设计模式。请参阅上面迈克尔的回答。
        • 好吧,我不知道这是否是世界上最好的做法,在这种特殊情况下很难看到任何好处,但我不同意这违反了 Liskov 的替代原则。如果 OP 要创建一个 CLLocationManager 的子类,该子类设置为它自己的委托,这本身不会破坏这个子类在/如果它的委托随后设置为其他对象时执行的能力,所以这个子类应该仍然能够执行为 CLLocationManager.. 除了自己的 API 外,它仅被扩展为实现协议..
        • @Jef:OP 没有询问是否可以将委托设置为 self,而是询问是否遵循 iOS 惯例。而且我并没有说将委托属性指向 self 会自动违反 LSP。我刚才说了,在实践中,很难创造出一个委托指向自己不违反 LSP 的情况。我知道这似乎令人毛骨悚然,但我预料到了这次讨论,因此我以我的方式制定了我最初的答案。无论如何,结论应该是恕我直言,在大多数情况下应该避免将代表指向自己。
        • 我认为,在大多数情况下,将委托指向 self 确实违反了 LSP,但如果不这样做,它仍然违反委托合同。委托是一种组合技术,旨在使对象可扩展而无需对其进行子类化。无论如何,对它进行子类化对我来说似乎很可疑。对我来说,委托合同似乎暗示:“这些是我无法实现的功能。这是你(委托人)的任务”。一个将其代表指向自我的子类说:“我比我的父类更了解”。所以我同意@DuncanC 的观点,它会颠覆委托设计模式。
        猜你喜欢
        • 2011-02-07
        • 1970-01-01
        • 2010-09-21
        • 2019-04-03
        • 2021-07-18
        • 1970-01-01
        • 1970-01-01
        • 2016-09-25
        • 1970-01-01
        相关资源
        最近更新 更多