【问题标题】:Swift 2 Protocol Extensions and Conformance for Objective-C TypesObjective-C 类型的 Swift 2 协议扩展和一致性
【发布时间】:2015-11-29 01:45:44
【问题描述】:

我有这样的设置:

@interface Model: NSManagedObject
...
@end

还有一个像这样的 Swift 协议:

@objc protocol Syncable {
    var uploadURL: String { get }
    var uploadParams: [String: AnyObject]? { get }
    func updateSyncState() throws
}

extension Syncable where Self: NSManagedObject {
    func updateSyncState() throws {
        ... /* default implementation */ ...
    }
}

在一个新的 Swift 文件中,我尝试这样做:

extension Model: Syncable {
    var uploadURL: String {
        return "a url"
    }
    var uploadParams: [String: AnyObject]? {
        return [:]
    }
}

我不断收到错误消息,Xcode 说“类型‘模型’不符合协议‘同步’”。 Xcode 还一直建议我在扩展程序中的某个位置放置一个@objc,但它似乎无法弄清楚它应该放在哪里。

我正在做的事情是不可能的吗? (它似乎在操场上的简单条件下工作 - 但显然我的 Objective-C 类是用 Swift 编写的)。

如果不可能,请帮助理解原因。

【问题讨论】:

    标签: objective-c swift protocol-extension


    【解决方案1】:

    问题在于尝试混合 Objective-C 和 Swift 的特性。这个纯 Swift 代码编译得很好(请注意,我已经从故事中删除了 NSManagedObject,因为它与问题无关):

    class MyManagedObject {}
    
    class Model: MyManagedObject {}
    
    protocol Syncable {
        var uploadURL: String { get }
        var uploadParams: [String: AnyObject]? { get }
        func updateSyncState()
    }
    
    extension Syncable where Self: MyManagedObject {
        func updateSyncState() {
        }
    }
    
    extension Model: Syncable {
        var uploadURL: String {
            return "a url"
        }
        var uploadParams: [String: AnyObject]? {
            return [:]
        }
    }
    

    那是因为 Swift 知道什么是协议扩展。但是Objective-C没有!因此,只要您说 @objc protocol,您就将协议移动到 Objective-C 世界,协议扩展没有任何效果 - 因此 Model 不符合要求,因为它没有 updateSyncState 实现。

    【讨论】:

    • 嗯...你是对的。但有趣的是,在我的操场上,我有一些与你发布的非常相似的东西,但我的协议确实@objc,而且事情仍然有效。
    • 嗯,游乐场不是应用程序。在操场上测试某些东西确实具有误导性。我总是在真实的应用中进行测试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多