【问题标题】:Convenience inits in class hierarchy cause infinite recursion类层次结构中的便利初始化导致无限递归
【发布时间】:2015-08-06 14:32:08
【问题描述】:

我在 Swift 2.0 中有 2 个类的层次结构。这两个类都可以通过传递参数或传递包含参数的 JSON 字典 ([String: AnyObject]) 来实例化。

直接接受参数的init是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"


    }

}

SubThing中的convenience init不允许在super中调用同一个init,如果我在self中调用它会导致无限递归,因为这两种方法have the same signature

如果我将两个 json 初始化为 designated,我无法在 Thing 中调用 self.init(name:),我将不得不在 Thing 中的两个初始化程序中重复相同的代码。

解决这种情况的最佳方法是什么?

【问题讨论】:

    标签: swift initialization swift2 designated-initializer


    【解决方案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"
        }
    }
    

    经过测试和工作。 更新:添加了私有初始化,所以它不能被初始化为空。

    【讨论】:

    • 我决定将所有 json 解析从 inits 中移出并放入一个函数,该函数返回一个包含所有正确和类型信息的结构,类似于 Aeson 为 Haskell 所做的。您的回答使我朝着正确的方向前进,谢谢! :-)
    猜你喜欢
    • 1970-01-01
    • 2014-09-07
    • 1970-01-01
    • 2017-12-21
    • 2023-02-18
    • 1970-01-01
    • 1970-01-01
    • 2018-02-21
    • 1970-01-01
    相关资源
    最近更新 更多