#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.