Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从json初始化子类_Json_Swift_Inheritance_Swift Protocols - Fatal编程技术网

从json初始化子类

从json初始化子类,json,swift,inheritance,swift-protocols,Json,Swift,Inheritance,Swift Protocols,我正在寻找一种保存任意子类的好方法 我在保存和加载时都在写对象。结构是具有不同类型的单元的组s。组只知道它的单位是实现UnitProtocol的东西 Unit的子类UAetc具有与单元完全相同的数据。因此,在数据方面,asDictionary和init(json)非常适合单元。子类仅在逻辑上有所不同。所以当从文件中恢复它们时,我相信它必须是初始化的确切子类 (糟糕)我想到的解决方案 让每个组都知道它可以拥有不同子类的单元,方法是不将它们仅作为[UnitProtocol]保存,而是作为[UA],

我正在寻找一种保存任意子类的好方法

我在保存和加载时都在写对象。结构是具有不同类型的
单元的
s。
只知道它的单位是实现
UnitProtocol
的东西

Unit
的子类
UA
etc具有与单元完全相同的数据。因此,在数据方面,
asDictionary
init(json)
非常适合
单元
。子类仅在逻辑上有所不同。所以当从文件中恢复它们时,我相信它必须是初始化的确切子类

(糟糕)我想到的解决方案
  • 让每个组都知道它可以拥有不同子类的单元,方法是不将它们仅作为
    [UnitProtocol]
    保存,而是作为
    [UA]
    [UB]
    等保存,它们可以单独保存,由各自的子初始化还原,并在初始化时合并为
    [UnitProtocol]
  • 使用子单元的类名存储子单元,并创建一个
    Unit.Init(json)
    ,它能够根据子类型传递初始化
  • ???我仍在思考,但我相信我可以在这里学到一些东西,以一种可维护的方式做到这一点,而不违反单一责任政策

  • 对于json中的init类,我使用了以下技术:

            //For row in json
            for row in json {
                //namespace it use for init class
                let namespace = (Bundle.main.infoDictionary!["CFBundleExecutable"] as! String).replacingOccurrences(of: " ", with: "_")
                //create instance of your class
                if let myClass = NSClassFromString("\(namespace).\(row.name)") as? NameProtocol.Type{
                    //init your class
                    let classInit : NameProtocol = myClass.init(myArgument: "Hey")
                    //classInit is up for use
                }
            }
    

    对于json中的init类,我使用了以下技术:

            //For row in json
            for row in json {
                //namespace it use for init class
                let namespace = (Bundle.main.infoDictionary!["CFBundleExecutable"] as! String).replacingOccurrences(of: " ", with: "_")
                //create instance of your class
                if let myClass = NSClassFromString("\(namespace).\(row.name)") as? NameProtocol.Type{
                    //init your class
                    let classInit : NameProtocol = myClass.init(myArgument: "Hey")
                    //classInit is up for use
                }
            }
    

    用它的类名存储每个单元json

    func asDictionary() -> Dictionary<String, Any> {
        let className = String(describing: type(of: self))
    
        let d = Dictionary<String, Any>(
            dictionaryLiteral:
            ("className", className),
    
            ("someUnitData", someUnitData),
            // and so on, for all the data of Unit...
    

    这里的诀窍是,将类
    unitSubclass
    强制转换为
    UnitProtocol
    ,然后允许您调用其
    init(json)
    ,该协议中声明但在特定子类中实现,或者在其超类
    Unit
    中实现,如果属性都相同。

    使用其类名存储每个单元json

    func asDictionary() -> Dictionary<String, Any> {
        let className = String(describing: type(of: self))
    
        let d = Dictionary<String, Any>(
            dictionaryLiteral:
            ("className", className),
    
            ("someUnitData", someUnitData),
            // and so on, for all the data of Unit...
    


    这里的诀窍是,将类
    unitSubclass
    强制转换为
    UnitProtocol
    ,然后允许调用其
    init(json)
    在该协议中声明但在特定子类中实现,或者在其超类
    Unit
    中实现(如果属性都相同)。

    Ok,因此,使用这种技术,我会将名称空间和类名存储在单元json中?@JOG您只需要存储类名,例如:[{“name”:“MyClassA”,“init”:“Horus”},{“name”:“MyClassB”,“init”:“JOG”}]您能解释一下NameProtocol.键入解决方案的一部分吗?好的,因此,使用这种技术,我将在单元json中存储名称空间和类名?@JOG您只需要存储类名,例如:[{“name”:“MyClassA”,“init”:“Horus”},{“name”:“MyClassB”,“init”:“JOG”}]请您解释一下NameProtocol。键入解决方案的一部分?您是否有理由避免使用透明处理所有这些问题的
    NSKeyedArchiver
    ?如果JSON的唯一目标是保存和恢复对象,那么它似乎需要做大量的工作,但没有任何好处。我如何使用它?如果你的意思是“为什么使用json?”是因为当数据离开iOS并变得混浊时,我喜欢json。请注意,Swift 4将有一个更强大的解决方案。你看(但要过几个月左右才会有)我不知道你说的“多云”是什么意思。您真的需要将其发布到需要JSON的服务吗?(iCloud是一个“云”服务,完全不需要JSON即可工作。)您为什么要避免透明地处理所有这些问题的
    NSKeyedArchiver
    ?如果JSON的唯一目标是保存和恢复对象,那么它似乎需要做大量的工作,但没有任何好处。我如何使用它?如果你的意思是“为什么使用json?”是因为当数据离开iOS并变得混浊时,我喜欢json。请注意,Swift 4将有一个更强大的解决方案。你看(但要过几个月左右才会有)我不知道你说的“多云”是什么意思。您真的需要将其发布到需要JSON的服务吗?(iCloud是一个“云”服务,完全没有JSON就可以工作。)这非常非常危险。永远不要基于从API收到的数据创建类。这是一个非常典型的漏洞。您应该知道系统处理什么类。创建JSON名称到类型的字典。(如果不清楚,我会写一个例子。)千万不要对通过网络收到的东西调用
    NSClassFromString
    。啊哈,你的意思是检查类名是否是我期望的类名之一?是的。否则,您可能会收到一些对您调用的方法做出响应的任意内容。这是Java世界中一个非常常见的漏洞(在Java世界中,从网络反序列化任意内容非常常见)。所以,我需要这样的东西来列出实现我的UnitProtocol的所有类,对吗?(还有一种使用“寄存器”的常见模式)方法更新字典,以便类可以注册自己。如果它们是
    NSObject
    子类,则可以将其放入
    +load
    中,它将在程序开始时自动运行。但这通常是过分的;同样,如果它非常复杂,您可能有太多的类。)这非常,非常危险。永远不要基于从API收到的数据创建类。这是一个非常典型的漏洞。您应该知道系统处理什么类。创建JSON名称到类型的字典。(如果不清楚,我会写一个例子。)千万不要对通过网络收到的东西调用
    NSClassFromString
    。啊哈,你的意思是检查类名是否是我期望的类名之一?是的。否则,您可能会收到一些对您调用的方法做出响应的任意内容。这是Java世界中一个非常常见的漏洞(在Java世界中,从网络反序列化任意内容非常常见)。所以,我需要这样的东西来列出实现我的UnitProtocol的所有类,对吗