Ios 迅捷王国。如何在数据库中放入300万个对象
我制作离线字典应用程序。现在我将字典文件转换为领域数据库 转换功能:Ios 迅捷王国。如何在数据库中放入300万个对象,ios,swift,database,realm,Ios,Swift,Database,Realm,我制作离线字典应用程序。现在我将字典文件转换为领域数据库 转换功能: if let path = Bundle.main.path(forResource: "dictionary", ofType: "dsl") { do { let data = try String(contentsOfFile: path, encoding: .utf8) let myStrings = data.components(separatedB
if let path = Bundle.main.path(forResource: "dictionary", ofType: "dsl") {
do {
let data = try String(contentsOfFile: path, encoding: .utf8)
let myStrings = data.components(separatedBy: .newlines)
for (index, row) in myStrings.enumerated() {
if(row.containsChineseCharacters)
{
let firstWord = CNDict()
firstWord.word = row
firstWord.pinyin = myStrings[index+1]
firstWord.translate = myStrings[index+2]
try! realm.write {
realm.add(firstWord)
}
}
}
print("The task end.")
} catch {
print(error)
}
}
当我试图立即转换字典时,数据库文件会变成大量GB,并在中间崩溃
将字典拆分为部分不是一个选项,因为大约有300万行。这将需要很多时间。。。(领域插件崩溃)
我需要有关如何在崩溃时向数据库添加尽可能多的值的帮助。问题是您的文件很大,此时,您将其加载到内存中:
let data = try String(contentsOfFile: path, encoding: .utf8)
然后将内存占用空间增加一倍:
let myStrings = data.components(separatedBy: .newlines)
我猜你收到了来自系统的内存不足信号
您可以使用lazy
collection,而不是将所有数据加载到内存中并将其加倍。它将只在需要写入时读取和解析该行。它不会一次加载所有线路。Swift中惰性集合的一个缺点是它们不能提供我们已经习惯的所有功能
这里是解决您的问题的操场的完整代码。您可以而且可能应该优化它的某些部分,但无论如何,它只是展示了如何使用lazy
集合进行优化。(我改了一些名字,但这仍然是你想要的)
<代码>导入基础
扩展字符串{
var包含符号:Bool{
返回包含(“1”)
}
}
扩展字符{
变量isNewLine:Bool{
让string=string(self)
let set=CharacterSet(charactersIn:string)
return!set.isDisjoint(带:CharacterSet.newlines)
}
}
///为领域添加对象子类
@OBJC成员
最后一节课{
动态变量word=“”
动态var拼音=“”
动态变量translate=“”
}
最终类ModelWriterRapper{
专用let缓冲容量=3
专用变量缓冲区:[字符串]=[]
init(){
缓冲区。保留容量(缓冲区容量)
}
func进程(行:字符串){
guard buffer.count==缓冲区容量else{
断言(buffer.count如果您对代码有任何疑问,请询问。上下文是什么,每个用户的手机上是否都有一个300万元素的字典,当他们更新时会转换为自己的领域数据库?是否有可能在服务器上预填充数据库?请共享
CNDict
Realm模型以查看其是否正确。另一个致命错误是:索引超出范围,因为最后一个索引+1
和索引+2
可能会增加。问题有点模糊。一般来说,在发布问题时,最好包含详细信息,以便我们了解用例。例如,什么是字典文件?你的数据结构是什么?正如前面的评论中提到的,索引+1没有任何上下文,所以我们不知道它是什么。什么是CNDict?3M线相当多,可能会使设备过载,你能把数据分块带过来而不是一次全部读取吗?也许一行一行地处理文件?请花点时间复习:。
import Foundation
extension String {
var containsOneSymbol: Bool {
return contains("1")
}
}
extension Character {
var isNewLine: Bool {
let string = String(self)
let set = CharacterSet(charactersIn: string)
return !set.isDisjoint(with: CharacterSet.newlines)
}
}
/// Add Object subclass for Realm
@objcMembers
final class CNDict {
dynamic var word = ""
dynamic var pinyin = ""
dynamic var translate = ""
}
final class ModelWriterWrapper {
private let bufferCapacity = 3
private var buffer: [String] = []
init() {
buffer.reserveCapacity(bufferCapacity)
}
func proccess(line: String) {
guard buffer.count == bufferCapacity else {
assert(buffer.count < bufferCapacity, "Buffer failer count: \(buffer.count)!")
buffer.append(line)
return
}
if let firstLine = buffer.first, firstLine.containsOneSymbol {
let dict = CNDict()
dict.word = firstLine
dict.pinyin = buffer[1]
dict.translate = buffer[2]
print("Ready for writing into DB \n word: \(dict.word) pinyin: \(dict.pinyin) translate: \(dict.translate)")
}
buffer.removeFirst()
buffer.append(line)
}
}
let data = stride(from: 0, to: 100_000, by: 1).map { "Line number \($0)\n"}.joined()
var line: String = ""
let myLines = data.lazy.map { char -> String in
line.append(char)
guard !char.isNewLine else {
defer { line = "" }
return line
}
return ""
}.filter { !$0.isEmpty }
let databaseWritter = ModelWriterWrapper()
myLines.forEach {
databaseWritter.proccess(line: $0)
}