在 performBackgroundTask 闭包中抛出异常
Throwing an exception in performBackgroundTask closure
有一个功能,我正在使用 Cora Data 将网络响应中的数据存储到我的数据库中。如果某些数据丢失、为空或 null 等,该函数应抛出 DataError
异常。
数据库操作必须在 privateQueueContext
的后台任务上 运行。在将数据存储到数据库之前,我检查它是否已经存在(通过 fetchRequest
)。如果结果为空,我开始处理数据并将其存储到数据库中。
我可以从闭包外部抛出异常,但我也想在 performBackgroundTask
闭包中抛出异常,但出现构建错误。
方法如下:
private func processLittleItems(informationsFromWebServiceResponse : GetInformationsFromWebServiceResponse) throws {
guard let littleItemListDataFromResponse = informationsFromWebServiceResponse.littleItemList else {
throw DataError.dataMissing("littleItemList")
}
CoreDataStack.shared.persistentStoreContainer.performBackgroundTask { privateQueueContext in
for littleItem in littleItemListDataFromResponse {
let littleItemRequest = LittleItem.fetchRequest() as NSFetchRequest<LittleItem>
littleItemRequest.predicate = NSPredicate(format: "id = %@", littleItem.iD!)
littleItemRequest.fetchLimit = 1
do {
let littleItemlist = try privateQueueContext.fetch(littleItemRequest)
if (littleItemlist.isEmpty) {
let newLittleItem = LittleItem(context: privateQueueContext)
guard let littleItemId = littleItem.iD else {
return // HERE SHOULD BE THROW EXCEPTION, NOT JUST A RETURN
}
newLittleItem.id = littleItemId
newLittleItem.optionalThing = littleItem.optionalThing ?? false
}
} catch let error as NSError {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
}
do {
try privateQueueContext.save()
} catch let error as NSError {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
}
}
你能帮忙吗?
提前感谢您提供的任何帮助。
不幸的是,这并不容易。
如果 processLittleItems
的调用者期望函数出现异常(或 return 值),则它必须等到所有内容都已存储。因此,异步处理在这种情况下将不起作用。
所以你必须重新考虑如何在你的应用程序中完成错误处理:
- 要么
processLittleItems
的调用者需要等待,因此你必须移除后台作业并同步进行所有操作
- 或者调用者不能等待(因为这会阻塞 UI 线程)。在这种情况下,调用者可以提供一个完成处理程序,然后您可以从后台闭包中提交 error/success 代码。
Andreas Oetjen 是对的。你抛出的基本上是同步方法的异常,而不是异步方法。
一个选项是根据您的逻辑定义您自己的完成处理程序或回调,并使用它来发回错误并在需要时使用它。
示例:
private func processLittleItems(informationsFromWebServiceResponse : GetInformationsFromWebServiceResponse, completion: (_ error: Error?, object: Any?) -> Void)
以及发生异常时。
completion('your exception', nil)
希望对您有所帮助。
有一个功能,我正在使用 Cora Data 将网络响应中的数据存储到我的数据库中。如果某些数据丢失、为空或 null 等,该函数应抛出 DataError
异常。
数据库操作必须在 privateQueueContext
的后台任务上 运行。在将数据存储到数据库之前,我检查它是否已经存在(通过 fetchRequest
)。如果结果为空,我开始处理数据并将其存储到数据库中。
我可以从闭包外部抛出异常,但我也想在 performBackgroundTask
闭包中抛出异常,但出现构建错误。
方法如下:
private func processLittleItems(informationsFromWebServiceResponse : GetInformationsFromWebServiceResponse) throws {
guard let littleItemListDataFromResponse = informationsFromWebServiceResponse.littleItemList else {
throw DataError.dataMissing("littleItemList")
}
CoreDataStack.shared.persistentStoreContainer.performBackgroundTask { privateQueueContext in
for littleItem in littleItemListDataFromResponse {
let littleItemRequest = LittleItem.fetchRequest() as NSFetchRequest<LittleItem>
littleItemRequest.predicate = NSPredicate(format: "id = %@", littleItem.iD!)
littleItemRequest.fetchLimit = 1
do {
let littleItemlist = try privateQueueContext.fetch(littleItemRequest)
if (littleItemlist.isEmpty) {
let newLittleItem = LittleItem(context: privateQueueContext)
guard let littleItemId = littleItem.iD else {
return // HERE SHOULD BE THROW EXCEPTION, NOT JUST A RETURN
}
newLittleItem.id = littleItemId
newLittleItem.optionalThing = littleItem.optionalThing ?? false
}
} catch let error as NSError {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
}
do {
try privateQueueContext.save()
} catch let error as NSError {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
}
}
你能帮忙吗?
提前感谢您提供的任何帮助。
不幸的是,这并不容易。
如果 processLittleItems
的调用者期望函数出现异常(或 return 值),则它必须等到所有内容都已存储。因此,异步处理在这种情况下将不起作用。
所以你必须重新考虑如何在你的应用程序中完成错误处理:
- 要么
processLittleItems
的调用者需要等待,因此你必须移除后台作业并同步进行所有操作 - 或者调用者不能等待(因为这会阻塞 UI 线程)。在这种情况下,调用者可以提供一个完成处理程序,然后您可以从后台闭包中提交 error/success 代码。
Andreas Oetjen 是对的。你抛出的基本上是同步方法的异常,而不是异步方法。
一个选项是根据您的逻辑定义您自己的完成处理程序或回调,并使用它来发回错误并在需要时使用它。 示例:
private func processLittleItems(informationsFromWebServiceResponse : GetInformationsFromWebServiceResponse, completion: (_ error: Error?, object: Any?) -> Void)
以及发生异常时。
completion('your exception', nil)
希望对您有所帮助。