2015-03-16 2 views
0

Я ищу лучший способ структурирования класса с отказоустойчивым инициализатором удобства с дополнительными параметрами. Текущий код:Неудачный инициализатор удобства с дополнительными параметрами

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, я бы хотел, чтобы он завершился неудачей.

В настоящее время, он не будет строить, потому что:

Все сохраненные свойства экземпляра класса должны быть инициализированы перед возвращением ноль из инициализаторе

Не уверен, что я пропускаю.

Любые мнения относительно лучшего способа приблизиться к этому приветствуются.

ответ

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 знает, что это раздражает, но есть некоторые угловые случаи, с которыми трудно справиться.)

Смежные вопросы