2015-08-06 3 views
0

У меня есть иерархия из 2 классов в Swift 2.0. Оба класса могут быть созданы путем передачи аргументов или путем передачи JSON-словаря ([String: AnyObject]), который содержит аргументы.Удобство в иерархии классов вызывает бесконечную рекурсию

inits, которые непосредственно принимают аргументы designated inits, в то время как те, которые принимают JSON являются convenience inits с той же подписи.

class Thing { 
    let name : String 

    init(name: String){ 
     self.name = name 
    } 

    convenience init(jsonNamed: String){ 

     // read the json, parse and extract 
     // the name 
     self.init(name: "got this from JSON") 
    } 
} 

class SubThing : Thing{ 

    var surname : String 

    init(name: String, surname: String){ 
     self.surname = surname 
     super.init(name: name) 
    } 


    convenience init(jsonNamed: String){ 

     self.init(jsonNamed: "got this from JSON") 
     // extract surname 
     self.surname = "Got this from json" 


    } 

} 

convenience INIT в SubThing не может вызвать ту же инициализацию в супер, и если я называю это в себе, это приведет к бесконечной рекурсии, так как оба метода have the same signature.

Если я как JSON inits designated те, я не могу назвать self.init(name:) в Thing, и я должен был бы повторить тот же код в обоих инициализаторов в Thing.

Каков наилучший способ обойти эту ситуацию?

ответ

1

Вы делаете цикл в SubThing, вызывая тот же самый назначенный инициализатор от себя. Я вижу, что это переписано таким образом:

class Thing { 
    private var name : String? 

    private init() {} 

    convenience init(name: String){ 
     self.init() 
     self.name = name 
    } 

    convenience init(jsonNamed: String){ 
     self.init() 
     self.name = getNameFromJSON() 
    } 

    private func getNameFromJSON() -> String { 
     // read the json, parse and extract 
     // the name 
     return "got this from JSON" 
    } 
} 

class SubThing : Thing { 
    private var surname : String? 

    convenience init(name: String, surname: String){ 
     self.init(name: name) 
     self.surname = surname 
    } 


    convenience init(jsonNamed: String){ 
     self.init() 
     self.name = getNameFromJSON() 
     // extract surname 
     self.surname = "Got this from json" 
    } 
} 

Протестировано и работает. UPDATE: добавлены частные inits, поэтому его нельзя было инициализировать пустым.

+0

Я решил перенести все json-парсинг из inits и в функцию, которая возвращает структуру со всей правильной и типизированной информацией, подобной той, что [Aeson] (https://www.fpcomplete.com/school/ start-with-haskell/libraries-and-frameworks/text-manipulation/json) для Haskell. Вы отвечаете, поставив меня в правильном направлении, спасибо! :-) – cfischer

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