Swift 2协议扩展和对Objective-C类型的一致性 [英] Swift 2 Protocol Extensions and Conformance for Objective-C Types

查看:109
本文介绍了Swift 2协议扩展和对Objective-C类型的一致性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的设置:

@interface Model: NSManagedObject
...
@end

还有这样的Swift协议:

And a Swift protocol like this:

@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文件中,我尝试执行以下操作:

In a new Swift file, I try to do this:

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

我不断收到错误消息,Xcode说类型'Model'不符合协议'Syncable'". Xcode还一直建议我在扩展名中的某个位置放置@objc,但似乎无法弄清楚应该去哪里.

I keep getting an error, with Xcode saying "type 'Model' does not conform to protocol 'Syncable'". Xcode also keeps suggesting that I put an @objc somewhere in my extension but it can't seem to figure out where it should go.

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

Is what I'm doing impossible? (It seems to work under simple conditions in a playground - but with my Objective-C class being written in Swift, obviously).

如果不可能,请帮助理解为什么会得到赞赏.

If it is impossible, help in understanding why would be appreciated.

推荐答案

问题是尝试混合使用Objective-C和Swift功能.这段纯Swift代码可以很好地编译(请注意,我已从故事中删除了NSManagedObject,因为它与问题无关):

The problem is the attempt to mix Objective-C and Swift features. This pure Swift code compiles just fine (note that I've eliminated NSManagedObject from the story, as it has nothing to do with the issue):

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实现.

That's because Swift knows what a protocol extension is. But Objective-C doesn't! So as soon as you say @objc protocol you move the protocol into the Objective-C world, and the protocol extension has no effect - and thus Model doesn't conform, as it has no updateSyncState implementation.

这篇关于Swift 2协议扩展和对Objective-C类型的一致性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆