【问题标题】:Realm Swift adding object with String property having character count > 1874 is crashing领域 Swift 添加具有字符数 > 1874 的字符串属性的对象正在崩溃
【发布时间】:2016-10-06 16:03:57
【问题描述】:

我有一个包含 200K 行的 csv 文件。

每行包含 9 个值,所有行 String 字符数小于 2048,但 3 行字符数等于 4420。这些行索引分别为 134481、134482、134483。在行中的 9 个值中,最后一个字符串值很大。

当第 134481 行添加到领域或在领域中创建时,它会在 BpTree::create_root_from_mem 与 EXC_BAD_ACCESS(code=2, address=xxxxx) 崩溃

下面是 swift 代码 [swift version 2.2, xcode: 7.3, realmSwift: 1.1.0]...用于将 csv 对象添加到领域数据库。

此代码在后台队列中运行。我尝试跳过前 130k 行,即使这样它也恰好在第 134481 行崩溃。只有在减少字符串字符数之后,才添加对象而不会崩溃。

class PackageObject:Object {
    dynamic var id = ""
    dynamic var packageBatch = ""
    dynamic var packageCode = ""
    dynamic var packageDescription = ""
    dynamic var packageName = ""
    dynamic var packagelocalName = ""
    dynamic var packageNumber = ""
    dynamic var packageBuild = ""
    dynamic var packageSummary = ""
}

let filename = NSBundle.mainBundle().pathForResource("codes", ofType: "tsv")
    if let realm = try? Realm(configuration: configuration), data = try? String.init(contentsOfFile: filename!) {
        let block = 5000
        var lineNumber = 0
        print(realm.configuration.fileURL)

        data.enumerateLines({ (line, stop) in
            if lineNumber % block == 0 {
                print("begin: ", lineNumber)
                realm.beginWrite()
            }
            lineNumber += 1
            var strings = line.componentsSeparatedByString("\t")

            if lineNumber >= 134481 && lineNumber <= 134483 {
                // strings[8] count is about 3805
                // after reducing the count to 1874, the object
                // is successfully added to the realm, else a crash is observed.
                let count = strings[8].characters.count
                print(count, line.characters.count)
                let index = strings[8].endIndex.advancedBy(1931 - count)
                strings[8].removeRange(index..<strings[8].endIndex)
            }

            let packageObj = PackageObject(value: strings)
            realm.add(packageObj)
            //realm.create(PackageObject.self, value:strings)
            if lineNumber % block == 0 {
                print("commit: ", lineNumber)
                _ = try? realm.commitWrite()
            }
        })
    }

   // The last commitWrite is not handled...inside the block.
   // for the below condition...
   if lineNumber % block != 0 {
       _ = try? realm.commitWrite()
   }

领域文档说字符串属性可以小于 16MB,但这里它甚至不占用 10KB。

我没有发现字符串有什么问题,它只是纯英文文本。这是一个错误还是我必须以不同的方式添加对象。

【问题讨论】:

    标签: ios swift realm


    【解决方案1】:

    如果字符串属性被索引,升级到 2.0 可能会解决这个问题。

    旧版本在索引的实现方式上存在缺陷,导致当字符串具有足够长的公共前缀时会发生堆栈溢出,并且 2.0 更改了索引的存储方式以消除递归。

    【讨论】:

    • 这正是正在发生的事情,因为我有一个索引,而且它们确实有很长的共同前缀。 RealmSwift 2.0 是否可用于 Swift 2.3。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-31
    • 1970-01-01
    • 1970-01-01
    • 2015-10-17
    • 1970-01-01
    相关资源
    最近更新 更多