Сбой при добавлении объекта Realm Swift со свойством String, имеющим количество символов> 1874

#ios #swift #realm

#iOS #swift #realm

Вопрос:

У меня есть csv-файл с 200 тыс. строк.

каждая строка содержит 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 версии 2.2, xcode: 7.3, RealmSwift: 1.1.0] … для добавления объектов csv в базу данных realm.

Этот код выполняется в фоновой очереди. Я попытался пропустить первые 130 тысяч строк, и даже тогда он вылетает точно в строке 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 amp;amp; 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 говорится, что строковое свойство может быть меньше 16 МБ, но здесь оно даже не занимает 10 КБ.

Я не нахожу ничего плохого в строке, это просто обычный текст на английском языке. Это ошибка или мне нужно добавлять объекты другим способом.

Ответ №1:

Если свойство string проиндексировано, обновление до 2.0, вероятно, исправит это.

В более старых версиях был недостаток в том, как был реализован индекс, который приводил к переполнению стека, когда строки имеют достаточно длинные общие префиксы, а 2.0 изменил способ хранения индексов, чтобы удалить рекурсию.

Комментарии:

1. Кажется, что именно это и происходит, поскольку у меня есть индекс на нем, и у них есть длинные общие префиксы. доступен ли RealmSwift 2.0 для Swift 2.3.