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



我正在启动一个新的iOSSwift项目。我需要添加一些所有项目类都应继承的功能。与Objective C不同,并非Swift中的所有类都继承自任何特定类,即NSObject.例如

我无法创建AnyAnyObject类的扩展,就像我可以为NSObject创建一样。例如,下面的代码是可以的。

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

但是,扩展AnyObject给出编译器错误,

非标称类型"任何对象"无法扩展

因此,我决定使项目中的所有 swift 类都继承我的BaseClass,这实际上是从NSObject继承的。

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

和其他类,即

class OtherClass: BaseClass {
// have classTag
}

在我为我的团队制定策略之前,要继承BaseClass的所有类,我想知道默认情况下从NSObject继承所有类是否存在一些缺点。

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

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

protocol Base {
func work()
}
extension Base {
func work() {...}
}
struct AppState: Base {}
AppState().work()

如果您正在制作一个由其他类继承的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特定的功能。

最新更新