首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swift: withCheckedContinuation和Dispatch

Swift: withCheckedContinuation和Dispatch
EN

Stack Overflow用户
提问于 2022-07-08 11:42:14
回答 1查看 326关注 0票数 2

我正在修改一些使用公共完成的旧代码,以便使用Parse的新的异步/等待语法。以下是一个例子:

代码语言:javascript
复制
static func get(
    className: String,
    id: String,
    _ completion: @escaping (PFObject?) -> Void
) {
    let query = PFQuery(className: className)
    query.getObjectInBackground(withId: id) { object, _ in
        completion(object)
    }
}

正在变成这样:

代码语言:javascript
复制
static func get(
    className: String,
    objectId: String
) async -> PFObject? {
    let query = PFQuery(className: className)
    return await withCheckedContinuation { continuation in
        query.getObjectInBackground(withId: objectId) { result, _ in
            continuation.resume(returning: result)
        }
    }
}

但是,我以前也使用过DispatchQueue/QoS,因此旧的函数实际上如下所示:

代码语言:javascript
复制
static func get(
    className: String,
    id: String,
    _ completion: @escaping (PFObject?) -> Void
) {
    let query = PFQuery(className: className)
    DispatchQueue.global(qos: .userInteractive).async {
        query.getObjectInBackground(withId: id) { object, _ in
            DispatchQueue.main.async {
                completion(object)
            }
        }
    }
}

如何将它与异步/等待语法结合使用?有必要吗?

谢谢你的帮助

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-08 19:28:15

您可能希望在Swift任务中执行异步函数get(className:objectId:),使用此任务初始化器

代码语言:javascript
复制
func foo(
    className: String,
    objectId: String
) async -> PFObject? {
    await Task(priority: .userInitiated) {
        await get(className: className, objectId: objectId)
    }
    .value
}

注意,当使用此任务初始化器时,您将得到“结构化并发”,这意味着函数foo中的嵌入任务继承了调用函数的参与者上下文。也就是说,您可以安全地使用任何线程调用的结果。

这也意味着,如果运行函数foo()的任务被取消,嵌入的任务也将被取消。当然,取消是合作的,这意味着您需要显式地停止正在运行的任务。例如,在用例中首选的方法是使用withTaskCancellationHandler,它在PFQuery对象上调用cancel()。或者,当您有一个长时间运行的迭代任务时,您可以在任务进行期间以合理的步骤轮询该任务的取消状态。

还请阅读有关“分离”的内容,它们在取消和继承任务优先级方面的行为有所不同。

关于是否需要它的问题:我假设,您会问是否需要使用指定优先级:简短的回答:在许多用例中,只从函数的任何线程继承优先级可能更安全。

在您的情况下,我不会显式地更改它:当从低优先级的后台线程调用它时,您的任务也应该继承此优先级。没有理由在userInitiated中使它具有高度的优先级。否则,如果您的函数已经从用户操作中调用,它也将继承这个更高的优先级。我相信,这是大多数用例所需要的。

而且,当您的工作人员在后台线程中运行时,就像代码中的情况一样,这个任务“安排得多快”并不重要。

因此,基本上您最终得到了定义的异步get函数,按原样使用,一切都很好。;)

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72910872

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档