子类NSCoder - 是否可以使用初始值设定项?

时间:2015-11-19 09:51:02

标签: swift init nscoder

我正在使用Xcode 7.2 beta。 我正在尝试使类模型符合NSCoding。

class Person: NSObject, NSCoding { 

Xcode希望我为此提供实现:

required init?(coder aDecoder: NSCoder) 

我看到我可以删除“?”,没有人抱怨。我也在swift编程语言doc中找到了这个:

“您通常会定义一个可用的初始化程序,通过在init关键字(init?)后面放置一个问号来创建相应类型的可选实例。或者,您可以定义一个可用的初始化程序,该程序创建一个隐式解包的可选实例。适当的类型。通过在init关键字(init!)之后放置感叹号而不是问号来执行此操作。

您可以从init委派吗?初始化!反之亦然,你可以覆盖init吗?用init!反之亦然。你也可以从init委托给init !,虽然这样做会触发init的断言!初始化程序导致初始化失败。“

我的代码可以使用或不使用“?” - 我相信因为这个可用的初始化器,它是如此多才多艺。有人可以解释一下吗?

我已经为初始化程序提供了这个:

  required init?(coder aDecoder: NSCoder) {
    super.init()
    name = aDecoder.decodeObjectForKey(Keys.Name) as! String
    id = aDecoder.decodeObjectForKey(Keys.ID) as! Int
    imagePath = aDecoder.decodeObjectForKey(Keys.ProfilePath) as! String
    movies = aDecoder.decodeObjectForKey(Keys.Movies) as! [Movie]
}

如果在没有可用的情况下实现init会有什么不同吗?

required init(coder aDecoder: NSCoder)

我已经完成了encodeWithCoder impl,因此初始化程序中不需要进行nil检查:

 func encodeWithCoder(aCoder: NSCoder) {
    aCoder.encodeObject(title, forKey: Keys.Title)
    aCoder.encodeObject(id, forKey: TheMovieDB.Keys.ID)
    aCoder.encodeObject(posterPath, forKey: Keys.PosterPath)
    aCoder.encodeObject(releaseDate, forKey: Keys.ReleaseDate)
}

您建议使用NSKeyedArchiver / NSKeyedUnarchiver哪一个?

2 个答案:

答案 0 :(得分:0)

您的类/对象可以将init函数中的任何项目处理为nil吗?你没有宣布它们是可选的,所以我假设答案是否定的。

如果任何这些项目最终都是无法加载/不可归档的,那么您可以使用可用的初始化程序。在这种情况下,您将返回nil,这是一个失败案例。

有关可用初始值设定项的更多信息可以在in this Apple Swift blog post找到,我刚才看到了。

答案 1 :(得分:0)

这实际上非常有趣,我不知道你可以实现一个不可用的初始化程序,并且仍然可以使用Xcode编译抱怨非协议一致性。

您使用的初始化程序完全取决于您要表达的意图。考虑一下在您离开后出现的开发人员的情况。如果他们看到init?,他们会立即知道初始值设定项成功或返回nil,而init则承诺始终成功。在这种情况下,最好完全符合指定的协议,因为可以安全地假设Apple有充分的理由使初始化程序可用。