Проблема в том, что ваш файл имеет большой размер, и в этот момент вы загружаете его в память:
let data = try String(contentsOfFile: path, encoding: .utf8)
А затем удваиваете объем памяти здесь:
let myStrings = data.components(separatedBy: .newlines)
Поэтому я предполагаю, что вы получили из памяти сигнал из системы.
Вместо загрузки в память всех данных и их удвоения можно использовать lazy
collection.Он будет читать и анализировать строку только тогда, когда это необходимо для записи.Он не будет загружать все строки одновременно.Недостатком ленивых коллекций в Swift является то, что они не могут предоставить все функции, к которым мы привыкли.
Вот полный код игровой площадки, который решает вашу проблему.Вы можете и, возможно, должны оптимизировать некоторые его части, но в любом случае это просто показывает, как это можно сделать с помощью коллекции lazy
.(Я изменил некоторые имена, но это все еще то, что вы хотите).
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)
}
Если у вас есть какие-либо вопросы относительно кода, пожалуйста, спросите.