ios - Realm Swift 添加具有字符数 > 1874 的 String 属性的对象崩溃

标签 ios swift realm

我有一个包含 20 万行的 csv 文件。

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

当第 134481 行添加到 Realm 或在 Realm 中创建时,它在 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 对象添加到 realm 数据库。

此代码在后台队列中运行。我尝试跳过前 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()
   }

realm 文档说一个 String 属性可以小于 16MB,但这里甚至不到 10KB。

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

最佳答案

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

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

关于ios - Realm Swift 添加具有字符数 > 1874 的 String 属性的对象崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39875611/

相关文章:

java - Realm.io [Java] 通知 - 如何仅监听特定表中的更改?

ios - 清除完整的 Realm 数据库

android - OkBuck 和 Realm 的问题

iphone - iOS 多任务手势 - 禁用/启用

iphone - 是否可以将 UITapGestureRecognizer 附加到 UILabel 子类

ios - 通过 xib 文件的类没有标识符为 'searchSegue' 的 segue

arrays - 从 Swift 数组中获取随机元素出现

ios - Swift Game Center 保存高分功能不起作用

ios - 为什么在 ObjectiveC 中参数前面有一个 "_"?

swift - 关闭 Void -> Void