CSVImporter在viewdidload[Swift]之后开始导入
我想从.csv文件导入数据,所以我使用了CSVImporter。它工作正常,但在执行函数viewDidLoad的另一部分之前就开始导入 下面的代码只是一个测试,但我需要一个解决方案,确保CSVImporter在另一个viewDidLoad代码执行之前完成导入,或者一个在viewDidLoad之后自动启动的函数 这是我的密码:CSVImporter在viewdidload[Swift]之后开始导入,swift,csv,csv-import,Swift,Csv,Csv Import,我想从.csv文件导入数据,所以我使用了CSVImporter。它工作正常,但在执行函数viewDidLoad的另一部分之前就开始导入 下面的代码只是一个测试,但我需要一个解决方案,确保CSVImporter在另一个viewDidLoad代码执行之前完成导入,或者一个在viewDidLoad之后自动启动的函数 这是我的密码: var Vokabeln: [[String]]? var i = 0 override func viewDidLoad() { super.viewDi
var Vokabeln: [[String]]?
var i = 0
override func viewDidLoad() {
super.viewDidLoad()
let path = "/Users/---CENSORED---/Documents/TestLöschen/TestLöschen/Vokabeln.csv"
let importer = CSVImporter<[String]>(path: path, delimiter: ";")
importer.startImportingRecords { $0 }.onFinish { importedRecords in
for record in importedRecords {
self.Vokabeln?[self.i][0] = record[0]
self.Vokabeln?[self.i][1] = record[1]
self.Vokabeln?[self.i][2] = record[2]
print("Begin1")
print(record[0])
print(record[1])
print(record[2])
print("End1")
self.i += 1
}
}
print("Begin2")
print(Vokabeln?[0][0])
print(Vokabeln?[0][1])
print(Vokabeln?[0][2])
print(Vokabeln?[1][0])
print(Vokabeln?[1][1])
print(Vokabeln?[1][2])
print("End2")
}
var-Vokabeln:[[String]]?
变量i=0
重写func viewDidLoad(){
super.viewDidLoad()
let path=“/Users/--censtered-/Documents/TestLỏschen/TestLỏschen/Vokabeln.csv”
let importer=CSVImporter(路径:路径,分隔符:“;”)
importer.startImportingRecords{$0}.onFinish{importedRecords in
对于导入记录中的记录{
self.Vokabeln?[self.i][0]=记录[0]
self.Vokabeln?[self.i][1]=记录[1]
self.Vokabeln?[self.i][2]=记录[2]
打印(“开始1”)
打印(记录[0])
打印(记录[1])
打印(记录[2])
打印(“End1”)
self.i+=1
}
}
打印(“开始2”)
打印(Vokabeln?[0][0])
打印(Vokabeln?[0][1])
打印(Vokabeln?[0][2])
打印(Vokabeln?[1][0])
打印(Vokabeln?[1][1])
打印(Vokabeln?[1][2])
打印(“End2”)
}
所以它先打印“Begin2”,然后6次打印“nil”。然后,当函数viewDidLoad完成时,它会打印“Begin1”,然后是正确的变量和“End1”
有人能帮我吗?
谢谢。
startImportingRecords
是异步工作的,只需在重复循环之后,将用于打印Vokabeln
的代码放在完成处理程序中
首先,您需要初始化数组,否则不会追加任何内容。不要将数组声明为可选,变量名应该以小写字母开头
var vokabeln = [[String]]()
例如,如果要更新UI,请将代码包装在分派块中
importer.startImportingRecords { $0 }.onFinish { importedRecords in
for record in importedRecords {
self.vokabeln[self.i][0] = record[0]
self.vokabeln[self.i][1] = record[1]
self.vokabeln[self.i][2] = record[2]
print("Begin1")
print(record[0])
print(record[1])
print(record[2])
print("End1")
self.i += 1
}
DispatchQueue.main.async {
print("Begin2")
print(self.vokabeln[0][0])
print(self.vokabeln[0][1])
print(self.vokabeln[0][2])
print(self.vokabeln[1][0])
print(self.vokabeln[1][1])
print(self.vokabeln[1][2])
print("End2")
}
}
但还有一个问题。如果将数组声明为[[String]]
则外部数组和内部数组均为空,并且不能使用索引下标赋值。我建议使用这种语法
for record in importedRecords {
self.vokabeln.append(record) // this appends the whole record array
print("Begin1")
print(record)
print("End1")
}
PS:考虑使用一个更适合的文本格式,如JSON或属性列表。
<代码> StestMtRoimtRebug < /Cord>异步工作,只需在重复循环后,在完成处理程序中将代码打印为<代码> Vokabeln < /C>。 首先,您需要初始化数组,否则不会追加任何内容。不要将数组声明为可选,变量名应该以小写字母开头var vokabeln = [[String]]()
例如,如果要更新UI,请将代码包装在分派块中
importer.startImportingRecords { $0 }.onFinish { importedRecords in
for record in importedRecords {
self.vokabeln[self.i][0] = record[0]
self.vokabeln[self.i][1] = record[1]
self.vokabeln[self.i][2] = record[2]
print("Begin1")
print(record[0])
print(record[1])
print(record[2])
print("End1")
self.i += 1
}
DispatchQueue.main.async {
print("Begin2")
print(self.vokabeln[0][0])
print(self.vokabeln[0][1])
print(self.vokabeln[0][2])
print(self.vokabeln[1][0])
print(self.vokabeln[1][1])
print(self.vokabeln[1][2])
print("End2")
}
}
但还有一个问题。如果将数组声明为[[String]]
则外部数组和内部数组均为空,并且不能使用索引下标赋值。我建议使用这种语法
for record in importedRecords {
self.vokabeln.append(record) // this appends the whole record array
print("Begin1")
print(record)
print("End1")
}
PS:考虑使用一个更适合的文本格式,如JSON或属性列表。
“CSVSouter在默认情况下异步工作,因此不会阻塞主线程。”阅读有关LIB的文档。不要阻塞主线程。在onFinish{}
闭包上调用方法的其余部分。或者同步阅读导入部分@Larme我已经同步制作了它,但他仍然打印了nil。“CSVImporter默认异步工作,因此不会阻塞主线程。”阅读关于lib的文档。不要阻塞主线程。在onFinish{}
闭包上调用方法的其余部分。或者同步阅读导入的部分@Larme我已经同步制作了它,但是他打印的是nil。因为你要将它用于具体的非可选数据。如果无法接收/转换数据,则阵列为空。这比可选绑定更易于使用,并且可以省略所有问号。不应将可选项用作I-don't-care的不在场证明。什么是调度阻止?带有打印的代码只是一个例子。真正的代码要大得多。建议在主线程的大括号内执行代码,例如更新用户界面。如果没有涉及UI,或者没有其他环境需要主线程,则不需要它。当我尝试初始化变量而不使用queation标记时,它再次给出错误“class viewcontroller没有初始化器,[[String]]
——无论是可选的还是非可选的——都是空的。内部数组和外部数组中都没有索引0。您需要插入或附加对象才能使用索引订阅。同样,var测试:[[String]]
不会初始化数组,您只是声明它,数组是nil
。另一个参数不使用optionals。因为您将使用它来处理具体的非可选数据。如果无法接收/转换数据,则阵列为空。这比可选绑定更易于使用,并且可以省略所有问号。不应将可选项用作I-don't-care的不在场证明。什么是调度阻止?带有打印的代码只是一个例子。真正的代码要大得多。建议在主线程的大括号内执行代码,例如更新用户界面。如果没有涉及UI,或者没有其他环境需要主线程,则不需要它。当我尝试初始化变量而不使用queation标记时,它再次给出错误“class viewcontroller没有初始化器,[[String]]
——无论是可选的还是非可选的——都是空的。内部数组和外部数组中都没有索引0。您需要插入或附加对象才能使用索引订阅。同样,var测试:[[String]]
不会初始化数组,您只是声明它,数组是nil
。另一个不使用的论点