【问题标题】:Iterate through dictionary of string, customObject and call customObject initialiser遍历字符串字典、customObject 并调用 customObject 初始化程序
【发布时间】:2017-05-29 03:30:42
【问题描述】:

我有一个包含许多 json 文件的文件夹。例如:

a.json
b.json
c.json
c.json2
c.json3

每个文件都包含我需要插入领域数据库的数据。 a=一种对象,b=另一种对象,c.json1、c.json2、c.json3都是同一种对象,但由于内容多,分为3个文件。

我没有为每种类型的对象分别创建一个 for 循环,而是尝试创建一个字典,我可以为我的第二个 for 循环迭代。

var filesToProcess : [String: Object] =
["a.json" : A(), "b.json" : B(), "c.json" : C()]

    for (str, obj) in filesToProcess {
        let numFiles = FileCounter().getNumFilesStartingWith(filename : str, url : unzippedDestinationUrl)
        for i in 0...numFiles {
            var append : String = ""
            i == 0 ? (append = "") : (append = String(i))
            if let jsonData = try? Data(contentsOf: unzippedDestinationUrl.appendingPathComponent(str+append)){
                if let array = (try? JSONSerialization.jsonObject(with: jsonData, options: [])) as? [[String: Any]] {
                    for item in array{
                        let itemJsonStr = item["data"] as! String
                        let item = obj(jsonStr : itemJsonStr)
                        DispatchQueue(label: "background").async {
                            let realm = try! Realm()
                            try! realm.write {
                                realm.add(item)
                            }
                        }
                    }
                }
            }
        }

    }

其中 A、B 和 C 是这样的对象:

import Foundation
import RealmSwift
import Realm

open class A : Object {

open dynamic var _id : String = ""
open dynamic var prop1 : Int = 0
open dynamic var prop2 : String = ""

open override class func primaryKey() -> String? {
    return "_id"
}
required public init() {
    super.init()
}

public init(jsonStr: String)
{
    if let dataDict = try? JSONSerializer.toDictionary(jsonStr){
        self._id = dataDict ["id"] as! String
        self.prop1 = dataDict ["prop1"] as! Int
        self.prop2 = dataDict ["prop2"] as! String
    }
    super.init()
}

required public init(realm: RLMRealm, schema: RLMObjectSchema) {
    super.init(realm: realm, schema: schema)
}

required public init(value: Any, schema: RLMSchema) {
    fatalError("init(value:schema:) has not been implemented")
}

}

但是在我的 for 循环中:

let item = obj(jsonStr : itemJsonStr)

我收到错误消息:

Cannot call value of Non-function type 'Object'

这有什么问题吗?我尝试做的事情是否可行,或者我应该坚持我已经做过的事情,即为每种类型的对象创建带有重复代码的单独循环?注意 A、B 和 C 具有不同的属性,但都使用 json 类型的输入字符串初始化

【问题讨论】:

    标签: swift string loops object dictionary


    【解决方案1】:

    你可以做一个新的功能

    func parse(jsonStr: String) {
        if let dataDict = try? JSONSerializer.toDictionary(jsonStr){
            self._id = dataDict ["id"] as! String
            self.prop1 = dataDict ["prop1"] as! Int
            self.prop2 = dataDict ["prop2"] as! String
        }
    }
    

    代替这一行

    //let item = obj(jsonStr : itemJsonStr)
    

    你可以这样做

    obj.parse(jsonStr: str)
    let item = obj
    

    【讨论】:

      【解决方案2】:

      obj 是一个对象的实例,你不能这样称呼它。

      实现您想要的一种方法是创建对象的公共超类(例如MyObject),在那里声明init(jsonStr: String) 并使您的字典如下所示:

      var filesToProcess : [String: MyObject] = ["a.json" : A.self, "b.json" : B.self, "c.json" : C.self]
      

      然后你就可以打电话了

      obj.init(jsonStr: ...)
      

      创建一个对象。

      您可以使用协议实现相同的目的。

      另一种方法是使用闭包来实现:

      var filesToProcess: [(String, (String) -> Object)] = [
          ("a.json", {json in A(jsonStr: json)}),
          ("b.json", {json in B(jsonStr: json)}),
          ("c.json", {json in C(jsonStr: json)})
      ]
      

      然后obj(jsonStr : itemJsonStr) 将真正起作用。

      (请注意,我使用的是 2 元组数组而不是字典)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-19
        • 1970-01-01
        • 1970-01-01
        • 2015-06-25
        • 2020-12-13
        • 1970-01-01
        相关资源
        最近更新 更多