具有可选参数的可用便捷初始化程序

时间:2015-03-16 19:52:45

标签: swift

我正在寻找使用带有可选参数的可用便捷初始化程序构建类的最佳方法。目前的代码:

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之前,必须初始化类实例的所有存储属性

不确定我错过了什么。

欢迎任何有关更好方法的意见。

1 个答案:

答案 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团队知道这很烦人,但是有一些难以处理的极端情况。)