为什么不直接扩展UIView或UIViewController?

Hon*_*ney 3 protocols swift swift-extensions protocol-oriented

我用这段代码看到了这个问题:

protocol Flashable {}

extension Flashable where Self: UIView 
{
    func flash() {
        UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseIn, animations: {
            self.alpha = 1.0 //Object fades in
        }) { (animationComplete) in
            if animationComplete == true {
                UIView.animate(withDuration: 0.3, delay: 2.0, options: .curveEaseOut, animations: {
                    self.alpha = 0.0 //Object fades out
                    }, completion: nil)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

而且我想知道为什么我们不只是直接扩展UIView?或者在类似的情况下延伸UIViewController为什么用a扭转它where Self:

  • 是这样我们增加了意图,当其他开发人员来时,他们会看到这个类符合Flashable,Dimmable等吗?
  • 我们的UIView还有单独的有意义的扩展吗?而不是UIView或UIViewController的不同unNamed扩展?
  • POP有关于此主题的特定Apple指南吗?我见过开发人员这样做,但不知道为什么......

das*_*ght 6

这种方法比UIView直接使用更好,如

extension UIView {
    func flash() {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

因为它允许程序员决定UIView他们希望制作哪些子类Flashable,而不是flash向所有UIViews 添加"批发"功能:

// This class has flashing functionality
class MyViewWithFlashing : UIView, Flashable {
    ...
}
// This class does not have flashing functionality
class MyView : UIView {
    ...
}
Run Code Online (Sandbox Code Playgroud)

从本质上讲,这是一种"选择加入"方法,而替代方法强制实现功能而无法"选择退出".

  • @Honey批量添加的问题是,闪存功能可用于您从未打算调用`flash()`的视图,编译器将无法帮助您检测这种情况.扩展成为所有`UIView`实现的一部分,包括那些尚未编码的实现.通过"不选择退出"我的意思是,一旦`扩展UIView`到位,Swift就不会为你提供一种语法来说"我不希望这个特定的`UIView`具有闪烁功能". (2认同)
  • 一点也不.@dasblinkenlight正是他所说的 - flash()可用于具有此扩展名的每个UIView(和UIKit子视图).考虑到这一点:如果这个UIView扩展是第三方插件的一部分,或者是团队维护的大型应用程序的一部分......你在哪里记录内容?你在哪里提供覆盖功能?谁会知道?是.您可以在UIView级别扩展它.但也许你应该在别处做. (2认同)