我正在寻找使用带有可选参数的可用便捷初始化程序构建类的最佳方法。目前的代码:
class Member: NSObject {
var uid: String
let avatarURL: NSURL
let created: NSDate
let email: String
let name: String
let provider: String
var posts = [Post]()
var comments = [Comment]()
// Initialize a member with raw data
init(uid: String, avatarURL: NSURL, created: NSDate, email: String, name: String, provider: String){
self.uid = uid
self.avatarURL = avatarURL
self.created = created
self.email = email
self.name = name
self.provider = provider
super.init()
}
convenience init?(snapshot: FDataSnapshot){
if let uid = snapshot.key {
if let avatarURLString = snapshot.value["avatarURL"] as? String {
if let avatarURL = NSURL(string: avatarURLString) {
if let memberCreated = snapshot.value["created"] as? NSDate {
if let memberEmail = snapshot.value["email"] as? String {
if let memberName = snapshot.value["name"] as? String {
if let memberProvider = snapshot.value["provider"] as? String {
self.init(uid: uid, avatarURL: avatarURL, created:memberCreated, email: memberEmail, name: memberName, provider: memberProvider)
}
}
}
}
}
}
}
return nil
}
}
我需要手动初始化成员(init)或传递Firebase对象(方便初始化)。如果任何一个选项在便利init中失败,我希望它失败。
目前,它不会构建,因为:
在从初始化程序
返回nil之前,必须初始化类实例的所有存储属性
不确定我错过了什么。
欢迎任何有关更好方法的意见。
答案 0 :(得分:2)
这是可用的初始化程序中的一个已知问题,Swift团队仍在努力改进。如您所说,在返回nil
之前,必须将所有属性设置为某些属性,因此请将它们设置为某些内容(""
或NSDate()
)。这有点乏味,但目前是必要的。
更清楚一点,因为它有时候有点棘手,这是一种方式:
convenience init?(snapshot: FDataSnapshot){
if let uid = snapshot.key {
if let avatarURLString = snapshot.value["avatarURL"] as? String {
if let avatarURL = NSURL(string: avatarURLString) {
if let memberCreated = snapshot.value["created"] as? NSDate {
if let memberEmail = snapshot.value["email"] as? String {
if let memberName = snapshot.value["name"] as? String {
if let memberProvider = snapshot.value["provider"] as? String {
self.init(uid: uid, avatarURL: avatarURL, created:memberCreated, email: memberEmail, name: memberName, provider: memberProvider)
return
}
}
}
}
}
}
}
self.init(uid: "", avatarURL: NSURL(), created: NSDate(), email: "", name: "", provider: "")
return nil
}
(在Swift 1.2中,您将能够将所有这些让它们叠加在一起,这将使代码更清晰,并允许您使用else
而不是return
中间。)
关键是,在便捷初始化程序中,您最终必须致电self.init
,即使您稍后再打电话给return nil
。 (Swift团队知道这很烦人,但是有一些难以处理的极端情况。)