Swift 中的协议扩展如何工作?

How does protocol extension work in Swift?

我正在开始一个新的 iOS Swift 项目。我需要添加一些所有项目 classes 都应该继承的功能。与 Objective C 不同,并非 Swift 中的所有 class 都继承自任何特定的 class,即 NSObject。例如,

我无法像 NSObject 那样创建 AnyAnyObject class 的扩展。例如,下面的代码就可以了。

extension NSObject {

    @objc var classTag: String {
        return String(describing: type(of: self))
    }
}

但是,AnyObject 上的扩展会导致编译器错误,

Non-nominal type 'AnyObject' cannot be extended

所以,我决定让我项目中的所有 swift class 继承自我的 BaseClass 而实际上是继承自 NSObject.

class BaseClass: NSObject {

    @objc var classTag: String {
        return String(describing: type(of: self))
    }
}

和其他 class,即

class OtherClass: BaseClass {
    // have classTag
}

在我为我的团队制定政策之前,从 BaseClass 继承所有 classes,我想知道从 BaseClass 继承所有 classes 是否有一些缺点默认 NSObject

如果你要让 BaseClass 被其他 类 继承,我认为甚至不需要从 NSObject 继承。

您可以简单地在 BaseClass 本身中添加 classTag,即

class BaseClass {
    var classTag: String {
        return String(describing: type(of: self))
    }
}

class SubClass: BaseClass {
    func someFunc() {
        print(self.classTag)
    }
}

另一种选择是使用 protocolprotocol extension 并提供 classTag 的默认定义,即

protocol SomeProtocol {
    var classTag: String { get }
}

extension SomeProtocol {
    var classTag: String {
        return String(describing: type(of: self))
    }
}

然后,您可以在任何需要的地方使 SomeProtocol 符合 类,即

class SubClass: SomeProtocol {
    func someFunc() {
        print(self.classTag)
    }
}

无论如何,从 NSObject 继承是不必要的,因为您不需要任何 NSObject 特定功能。

  • 类继承自NSObject不能final。当打开整个模块优化时,Swift 将在可能的情况下添加 final,但不会在 objective c 类 中添加。这是微优化,除非您有特殊情况,否则我真的不会考虑。
  • 考虑使用复制语义(使用结构)时,您将无法通过继承来扩展结构。
  • 您将在 IDE 中添加很多自动完成的噪音。
  • 使用协议 (POP) 可以为您提供更多 flexibility/power。像条件一致性等...如果需要,您可以扩展 NSObject。

考虑使用 protocol extension 和结构而不是 NSObject

protocol Base {
  func work()
}

extension Base {
  func work() {...}
}

struct AppState: Base {}

AppState().work()