6

我是 swift 的新手,我在 swift 中遇到了 initwithcoder 的问题。

我有类 UserItem,我需要它来保存用户登录。

在目标c中是这样的

 - (id)initWithCoder:(NSCoder *)decoder{
    if (self = [super init]){
        self.username = [decoder decodeObjectForKey:@"username"];
    }
    return self;
}

我很快就在尝试这样

override init() {
   super.init()
}    

required init(coder decoder: NSCoder!) {

   self.username = (decoder.decodeObjectForKey("username")?.stringValue)!

   super.init(coder: decoder)
}

但如果像上面一样,我会收到代码错误

super.init(coder: decoder)

错误消息是“调用中的额外参数‘编码器’

我想不通了,所以我试试这段代码,

convenience init(decoder: NSCoder) {
   self.init()

   self.username = (decoder.decodeObjectForKey("username")?.stringValue)!
}

但是,得到错误

.UserItem initWithCoder:]: unrecognized selector sent to instance 0x7fd4714ce010

我应该怎么办?之前感谢您的帮助。

4

1 回答 1

14

我过去曾在(用于归档和取消归档对象的协议)上苦苦挣扎,NSCoding我看到你正在经历同样的痛苦。希望这可以减轻一点:

class UserItem: NSObject, NSCoding {
    var username: String
    var anInt: Int

    init(username: String, anInt: Int) {
        self.username = username
        self.anInt = anInt
    }

    required init?(coder aDecoder: NSCoder) {
        // super.init(coder:) is optional, see notes below
        self.username = aDecoder.decodeObjectForKey("username") as! String
        self.anInt = aDecoder.decodeIntegerForKey("anInt")
    }

    func encodeWithCoder(aCoder: NSCoder) {
        // super.encodeWithCoder(aCoder) is optional, see notes below
        aCoder.encodeObject(self.username, forKey: "username")
        aCoder.encodeInteger(self.anInt, forKey: "anInt")
    }

    // Provide some debug info
    override var description: String {
        get {
            return ("\(self.username), \(self.anInt)")
        }
    }
}

// Original object
let a = UserItem(username: "michael", anInt: 42)

// Serialized data
let data = NSKeyedArchiver.archivedDataWithRootObject(a)

// Unarchived from data
let b = NSKeyedUnarchiver.unarchiveObjectWithData(data)!

print(a)
print(b)

重要的是匹配encodeWithCoder(aCoder:)(归档功能)和init(coder:)(取消归档功能)中的键和数据类型。

让初学者感到困惑的是如何处理超类。如果超类本身符合NSCoding. NSObject本身不提供。这个想法是每个类都知道自己的属性,其中一些是私有的。如果超类无法归档/取消归档,则无需调用它们。

于 2015-11-30T03:15:13.897 回答