Swift:不符合协议NSCoding

12

我试图在我用Swift编写的一个类上使用NSCoding协议,但似乎无法弄清为什么编译器会抱怨“它不符合协议NSCoding”,当我确实实现了所需的方法时:

class ServerInfo: NSObject, NSCoding {

    var username = ""
    var password = ""
    var domain = ""
    var location = ""
    var serverFQDN = ""
    var serverID = ""

    override init() {

    }

    init(coder aDecoder: NSCoder!) {
        self.username = aDecoder.decodeObjectForKey("username") as NSString
        self.password = aDecoder.decodeObjectForKey("password") as NSString
        self.domain = aDecoder.decodeObjectForKey("domain") as NSString
        self.location = aDecoder.decodeObjectForKey("location") as NSString
        self.serverFQDN = aDecoder.decodeObjectForKey("serverFQDN") as NSString
        self.serverID = aDecoder.decodeObjectForKey("serverID") as NSString
    }


    func encodeWithCoder(_aCoder: NSCoder!) {
        _aCoder.encodeObject(self.username, forKey: "username")
        _aCoder.encodeObject(self.password, forKey: "password")
        _aCoder.encodeObject(self.domain, forKey: "domain")
        _aCoder.encodeObject(self.location, forKey: "location")
        _aCoder.encodeObject(self.serverFQDN, forKey: "serverFQDN")
        _aCoder.encodeObject(self.serverID, forKey: "serverID")
    }

}

这是一个错误吗,还是我遗漏了什么?

3个回答

19

正如您可以在报告导航器中的详细编译器消息中看到的那样,您的方法未正确声明:

错误:类型“ServerInfo”不符合协议“NSCoding”
class ServerInfo:NSObject,NSCoding {
^
Foundation.NSCoding:2:32:注意:协议要求具有类型“(NSCoder)-> Void”的函数“encodeWithCoder”
@objc(encodeWithCoder :) func encodeWithCoder(aCoder:NSCoder)
                               ^
注意:候选人的类型不匹配“(NSCoder!)->()”
    func encodeWithCoder(_aCoder:NSCoder!){
         ^
Foundation.NSCoding:3:25:注意:协议要求具有类型“(coder:NSCoder) - > Self?”的初始化程序“init(coder :)”
@objc(initWithCoder :) init(coder aDecoder:NSCoder)
                        ^
注意:候选人的类型不匹配“(coder:NSCoder!)”
     init(coder aDecoder:NSCoder!){

(这可能在测试版发布之间已更改。) 另外,initWithCoder方法必须标记为required

required init(coder aDecoder: NSCoder) {   }

func encodeWithCoder(_aCoder: NSCoder) {   }

Swift 3中,必需的方法为:

required init(coder aDecoder: NSCoder) {   }

func encode(with aCoder: NSCoder) {   }

2
这可能在测试版之间发生了变化。是的,有时候我们会对 Swift 大喊:“伙计,这些方法签名是从你那里得到的!你怎么敢告诉我现在它们是错误的?”但当然,在快节奏的测试版中,这就是生活…… - matt
@matt:至少编译器在这里打印了一个明智的信息,而不是“$%§?& 无法转换为 UInt8” :) - Martin R
除了它抱怨的参数错误一半的时间! :)) - matt
@KunalGupta:你在使用Swift 3/Xcode 8吗?encode方法的签名已经改变,请查看更新后的答案。 - Martin R
1
@KunalGupta:Swift 3 发生了很多变化,请参见 https://swift.org/migration-guide/。这个特定的更改是 https://github.com/apple/swift-evolution/blob/master/proposals/0005-objective-c-name-translation.md 的一部分。 - Martin R
显示剩余2条评论

4
参数不是隐式解包的(删除!),初始化程序需要required修饰符:
required init(coder aDecoder: NSCoder) {
...
func encodeWithCoder(_aCoder: NSCoder) {

对于Swift 3

进行了一项次要但重要的更改。init方法不变,但encodeWithCoder方法已被修改。

   required init(coder aDecoder: NSCoder) {
    ...
   }

   func encode(with _aCoder: NSCoder) { 
   ...
   }

0

针对Swift 3(在Xcode 8.2 beta(8C23)上)

看起来又变了。这是我唯一能让它工作的变化...

func encodeWithCoder(_ _aCoder: NSCoder) {
    ...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接