【问题标题】:Throwing an exception in performBackgroundTask closure在 performBackgroundTask 闭包中抛出异常
【发布时间】:2023-04-02 16:05:01
【问题描述】:

有一个功能,我正在使用 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)")
        }
    }
}

你能帮忙吗?

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

【问题讨论】:

    标签: swift core-data swift4.2


    【解决方案1】:

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

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

    【讨论】:

    • 非常感谢,我不得不考虑这个功能!
    【解决方案2】:

    Andreas Oetjen 是对的。您基本上会为同步方法而不是异步方法抛出异常。

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

    private func processLittleItems(informationsFromWebServiceResponse : GetInformationsFromWebServiceResponse, completion: (_ error: Error?, object: Any?) -&gt; Void)

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

    希望对你有帮助。

    【讨论】:

    • 非常感谢,我不得不考虑这个功能!
    猜你喜欢
    • 2020-09-26
    • 2012-01-24
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    • 2013-05-24
    • 2011-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多