斯威夫特开放'关键字&扩展中的可覆盖方法/属性?

时间:2016-08-25 09:50:45

标签: ios swift syntax swift-extensions

在Swift 3.0中引入open关键字(What is the 'open' keyword in Swift?)。

注意:仅限于NSObject派生类或@objc归因方法/属性的附加信息。

在模块/框架中扩展publicclass)方法/属性声明并使用了代码,因为public不再意味着&# 39;可重写'在定义模块之外。

示例:

public extension UIManagedDocument {

    public class func primaryDocumentName() -> String {
        return "Document"
    }

    public class func primaryStoreURL() -> URL {
        let documentsURL = FileManager.default.userDocumentsURL
        return URL(fileURLWithPath: self.primaryDocumentName(), isDirectory: false, relativeTo: documentsURL)
    }

    public class func primaryModelName() -> String? {
        return "Model"
    }

}
  • 原始提案(SE-0117)专注于子类化,并不提及扩展。
  • 目前的扩展程序不支持open关键字(您无法写open extension NSObject以及open func Method()

问题:是否有解决方法可以跨模块/框架覆盖扩展提供的方法/属性

2 个答案:

答案 0 :(得分:8)

除非我弄错了,否则你可以将扩展方法声明为 如果您省略open关键字,则在您的框架中public 在扩展声明中:

extension UIManagedDocument {

    open class func primaryDocumentName() -> String {
        return "Document"
    }
    // ...
}

然后(对于NSObject子类或@objc成员),您可以覆盖该方法 在主应用程序(或任何模块)中的自定义子类中:

class MyManagedDocument: UIManagedDocument {

    override class func primaryDocumentName() -> String {
        return "MyDocument"
    }
    // ...
}

答案 1 :(得分:3)

  • '协议为本' - 使用所需的方法/属性声明 protocol ,然后重构协议合规性的扩展名。
  • '传统' - 使用所需的方法/属性实现中间(抽象)子类。

协议示例:

protocol PrimaryDocument {
    static func primaryDocumentName() -> String

    static func primaryStoreURL() -> URL

    static func primaryModelName() -> String?
}

extension UIManagedDocument : PrimaryDocument {

    open class func primaryDocumentName() -> String {
        return "Document"
    }

    open class func primaryStoreURL() -> URL {
        let documentsURL = FileManager.default.userDocumentsURL
        return URL(fileURLWithPath: self.primaryDocumentName(), isDirectory: false, relativeTo: documentsURL)
    }

    open class func primaryModelName() -> String? {
        return "Model"
    }

}