SWIFT:检查和调度QosClass
我正在调整一些旧代码,这些代码使用常见的完成来使用新的异步/等待SDK的等待语法。这是一个示例,以下
static func get(
className: String,
id: String,
_ completion: @escaping (PFObject?) -> Void
) {
let query = PFQuery(className: className)
query.getObjectInBackground(withId: id) { object, _ in
completion(object)
}
}
是这样的:
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
之前,因此旧功能实际上看起来像这样:
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)
}
}
}
}
我该如何使用此功能使用异步/等待语法?甚至需要吗?
感谢您的帮助
I am adapting some old code which was using common completions in order to use the new async/await syntax with Parse SDK. Here is an example, this:
static func get(
className: String,
id: String,
_ completion: @escaping (PFObject?) -> Void
) {
let query = PFQuery(className: className)
query.getObjectInBackground(withId: id) { object, _ in
completion(object)
}
}
is becoming this:
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)
}
}
}
However, I was also using DispatchQueue
/QoS
previously and so the old function actually looked like this:
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)
}
}
}
}
How can I use this with the async/await syntax? Is it even needed?
Thank you for your help
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可能要执行async函数
get(className:objectId:)在迅速任务中,使用此任务启动器:
请注意,使用此任务时启动器您正在获得“结构化并发”,这意味着函数中的嵌入式任务
foo
继承了调用函数的actor上下文。也就是说,您可以从所谓的任何线程中安全地使用结果。
这也意味着,如果正在运行函数
foo()
的任务,则将被取消,嵌入式任务也将被取消。当然,取消是合作的,这意味着您需要明确停止运行的任务。例如,正如您的用例中的首选一样,使用withTaskCancellationHandler
,在您的pfquery对象上调用cacture()
。或者,当您执行长期运行的迭代任务时,您可以在任务进展时以合理的步骤进行轮询任务的取消状态。还请阅读有关“独立”的信息,这些“分离”在取消和继承任务优先级方面行为不同。
作为您是否需要的问题:
我假设,您问是否需要使用指定优先级:
简短答案:在许多用例中,仅继承该函数启动的任何线程的优先级可能更安全。
就您而言,我不会明确更改它:当它从优先级低的背景线程调用时,您的任务也应继承此优先级。没有理由将其优先考虑
用户启用
。否则,如果您的函数已经从用户操作中调用,则它将继承更高的优先级。我相信,这是大多数用例所需要的。另外,当您的工人在背景线程中运行(与代码中的情况一样)时,“安排安排”此任务的确并不重要。
因此,基本上,您最终会以async
get
函数定义,并按原样使用它,所有这些都很好。 )You probably want to execute your async function
get(className:objectId:)
within a Swift Task, using this Task initialiser:Note that, when using this Task initialiser you are getting "structured concurrency", which means, that the embedded task in function
foo
inherits the actor context of the calling function.That is, you can use the result safely from whatever thread you called it.
That means also, if the task where function
foo()
is running, gets cancelled, the embedded task will be cancelled as well. Of course, cancellation is cooperatively, which means, you need to stop a running task explicitly. For example, as preferred in your use case, with awithTaskCancellationHandler
, which callscancel()
on your PFQuery object. Or when you have a long running iterating task, you may poll the Task's cancellation status in reasonably steps while your task progresses.Please also read about "detached" which behave differently regarding cancellation and inheriting the task priority.
As of your question whether it is needed:
I assume, you ask if using specifying a priority is needed:
Short answer: in many use cases it may be more safe to just inherit the priority from whatever thread the function originates.
In your case, I would not explicitly change it: when it is called from a background thread with low priority, your task should inheriting this priority as well. There will be no reason to make it high priority with
userInitiated
. Otherwise, if your function is already called from a user action, it will be inheriting this higher priority as well. I believe, this is what most use cases would require.Also, when your worker is running in a background thread, as is the case in your code, it really doesn't matter much "how fast you schedule" this task.
So, basically you end up with your async
get
function as defined, use it as is, and all is good. ;)