Swift 在performBackgroundTask关闭中引发异常

Swift 在performBackgroundTask关闭中引发异常,swift,core-data,swift4.2,Swift,Core Data,Swift4.2,有一个函数,我使用Cora数据将web响应中的数据存储到我的数据库中。如果某些数据丢失或为空或null等,函数应引发DataError异常。 数据库操作必须在具有privateQueueContext的后台任务上运行。在将数据存储到数据库之前,我检查它是否已经存在(通过fetchRequest)。如果结果为空,我开始处理数据并将其存储到数据库中 我可以从闭包外部抛出异常,但我也希望在performBackgroundTask闭包中抛出异常,但我得到一个生成错误 方法如下: private fun

有一个函数,我使用Cora数据将web响应中的数据存储到我的数据库中。如果某些数据丢失或为空或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)")
        }
    }
}
private func processLittleItems(来自WebServiceResponse的信息:GetInformationsFromWebServiceResponse)抛出{
guard let littleItemListDataFromResponse=来自WebServiceResponse.littleItemList的信息{
抛出DataError.dataMissing(“littleItemList”)
}
CoreDataStack.shared.persistentStoreContainer.performBackgroundTask{中的privateQueueContext
对于littleItemListDataFromResponse中的littleItem{
让littleItemRequest=LittleItem.fetchRequest()作为NSFetchRequest
littleItemRequest.predicate=NSPredicate(格式:“id=%@”,littleItem.id!)
littleItemRequest.fetchLimit=1
做{
let littleItemlist=try privateQueueContext.fetch(littleItemRequest)
如果(littleItemlist.isEmpty){
让newLittleItem=LittleItem(上下文:privateQueueContext)
guard let littleItemId=littleItem.iD else{
return//这里应该是抛出异常,而不仅仅是返回
}
newLittleItem.id=littleItemId
newLittleItem.optionalThing=littleItem.optionalThing??错误
}
}将let错误捕获为NSError{
fatalError(“未解决的错误\(error),\(error.userInfo)”)
}
}
做{
请尝试privateQueueContext.save()
}将let错误捕获为NSError{
fatalError(“未解决的错误\(error),\(error.userInfo)”)
}
}
}
你能帮忙吗


提前感谢您提供的任何帮助。

不幸的是,这并不容易。 如果
processLittleItems
的调用者期望函数出现异常(或返回值),则必须等待所有内容都被存储。因此,异步处理在这种情况下不起作用。 因此,您必须重新思考如何在应用程序中进行错误处理:

  • processLittleItems
    的调用方需要等待,因此您必须删除后台作业并同步执行所有操作
  • 或者调用方不能等待(因为这会阻塞UI线程)。在这种情况下,调用方可以提供一个完成处理程序,然后您可以从后台闭包中提供该处理程序并提交错误/成功代码

  • 不幸的是,这并不是那么容易。 如果
    processLittleItems
    的调用者期望函数出现异常(或返回值),则必须等待所有内容都被存储。因此,异步处理在这种情况下不起作用。 因此,您必须重新思考如何在应用程序中进行错误处理:

    • processLittleItems
      的调用方需要等待,因此您必须删除后台作业并同步执行所有操作
    • 或者调用方不能等待(因为这会阻塞UI线程)。在这种情况下,调用方可以提供一个完成处理程序,然后您可以从后台闭包中提供该处理程序并提交错误/成功代码

    安德烈亚斯·奥特扬说得对。对于同步方法而不是异步方法,基本上会抛出异常

    一个选项是根据您的逻辑定义自己的完成处理程序或回调,并使用它将错误发送回,并在需要时使用它。 样本:

    private func processLittleItems(来自WebServiceResponse的信息:GetInformation来自WebServiceResponse,完成:(\uError:error?,object:Any?)->Void)

    当异常发生时。
    completion('your exception',nil)


    希望能有所帮助。

    安德烈亚斯·奥特扬说得对。对于同步方法而不是异步方法,基本上会抛出异常

    一个选项是根据您的逻辑定义自己的完成处理程序或回调,并使用它将错误发送回,并在需要时使用它。 样本:

    private func processLittleItems(来自WebServiceResponse的信息:GetInformation来自WebServiceResponse,完成:(\uError:error?,object:Any?)->Void)

    当异常发生时。
    completion('your exception',nil)


    希望对您有所帮助。

    非常感谢,我不得不考虑这个函数!非常感谢,我不得不考虑这个函数!非常感谢,我不得不考虑这个函数!非常感谢,我不得不考虑这个函数!