Swift 'open' keyword & overridable method/properties in extension?

寵の児 提交于 2020-01-01 02:51:46

问题


With introduction of open keyword in Swift 3.0 (What is the 'open' keyword in Swift?).

Note: Limited to extensions on NSObject derived classes or @objc attributed method/properties.

Code wich declared and used public (class) methods/properties in extension across modules/frameworks broke, as public is no longer means 'overridable' outside of defining module.

Example:

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"
    }

}
  • Original proposal (SE-0117) is focused on subclassing and doesn't mention extensions.
  • Currently extensions do not support open keyword (you can't write open extension NSObject as well as open func Method())

Question: Is there workaround to be able override extension provided methods/properties across modules/frameworks?


回答1:


Unless I am mistaken, you can declare the extension methods as open in your framework if you just omit the public keyword in the extension declaration:

extension UIManagedDocument {

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

And then (for NSObject subclasses or @objc members) you can override the method in your custom subclass in the main application (or in any module):

class MyManagedDocument: UIManagedDocument {

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



回答2:


  • 'Protocol-oriented' - declare protocol with desired methods/properties then refactor your extension for protocol compliance.
  • 'Traditional' - implement intermediate (abstract) subclass with desired methods/properties.

Protocol example:

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"
    }

}


来源:https://stackoverflow.com/questions/39141975/swift-open-keyword-overridable-method-properties-in-extension

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!