简体   繁体   English

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

[英]How does protocol extension work in Swift?

I am starting a new iOS Swift project.我正在开始一个新的 iOS Swift项目。 I need to add some functionality that all of the project classes should inherit.我需要添加一些所有项目类都应该继承的功能。 Unlike Objective C not all classes in Swift are inherited from any particular class ie NSObject .Objective C不同,并非Swift中的所有类都继承自任何特定的 class 即NSObject For example,例如,

I cannot create extension of Any or AnyObject class, like I can for NSObject .我无法创建AnyAnyObject class 的扩展,就像我可以创建NSObject一样。 For example, below code is OK.例如,下面的代码是可以的。

extension NSObject {

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

But, extension on AnyObject give compiler error,但是, AnyObject上的扩展会导致编译器错误,

Non-nominal type 'AnyObject' cannot be extended非标称类型“AnyObject”无法扩展

So, I have decided to make all swift classes in my project to inherit from my BaseClass which is actually inherited from NSObject .所以,我决定让我的项目中的所有 swift 类继承自我的BaseClass ,它实际上是从NSObject继承的。

class BaseClass: NSObject {

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

And other classes ie和其他类,即

class OtherClass: BaseClass {
    // have classTag
}

Before I make a policy for my team, to inherit all classes from BaseClass , I want to know if there are some disadvantages of inheriting all the classes from NSObject by default.在我为我的团队制定政策之前,要从BaseClass继承所有类,我想知道默认情况下从NSObject继承所有类是否有一些缺点。

I don't think there is even a need to inherit from NSObject if you are making a BaseClass to be inherited by other classes.如果您要使BaseClass被其他类继承,我认为甚至不需要从NSObject继承。

You can simply add classTag in the BaseClass itself, ie您可以简单地在BaseClass本身中添加classTag ,即

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

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

Another option can be to use protocol and protocol extension and provide the default definition of classTag , ie另一种选择是使用protocolprotocol extension并提供classTag的默认定义,即

protocol SomeProtocol {
    var classTag: String { get }
}

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

Then, you can conform SomeProtocol to the classes wherever required, ie然后,您可以在任何需要的地方使SomeProtocol符合类,即

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

In any case, inheriting from NSObject is unnecessary since you don't need any NSObject specific functionality for that.无论如何,从NSObject继承是不必要的,因为您不需要任何NSObject特定功能。

  • Classes inherited from NSObject cannot be final .从 NSObject 继承的类不能是final While whole module optimization turned on, Swift will add final when possible but not in objective c classes.当整个模块优化打开时,Swift 将尽可能添加 final 但不在目标 c 类中。 This is micro optimization and I really won't consider unless you have really special case.这是微优化,除非您有特殊情况,否则我真的不会考虑。
  • When considering using copy semantics (using structs) you will not be able to extend your structs by inheritance.在考虑使用复制语义(使用结构)时,您将无法通过 inheritance 扩展您的结构。
  • You will add much noise in auto complete in IDE.您将在 IDE 的自动完成中添加很多噪音。
  • Using protocols (POP) can give you more flexibility/power.使用协议 (POP) 可以为您提供更大的灵活性/能力。 Like conditional conformance etc... And you can extend NSObject if needed.像条件一致性等......如果需要,您可以扩展 NSObject 。

Consider using protocol extension and maybe structs instead of NSObject .考虑使用protocol extension ,也许使用结构而不是NSObject

protocol Base {
  func work()
}

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

struct AppState: Base {}

AppState().work()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM