完成处理程序在任务完成之前返回
Completion handler returning before task finishes
我的这个函数有一个完成处理程序,该处理程序将在任务完成后返回,但从我得到的输出来看,它表明完成处理程序被认为已完成并在任务完成之前返回.
正在调用的函数:
private func getSteps(completion: (Int) -> ()) {
var val: Int = 0
guard let sampleType = HKObjectType.quantityType(forIdentifier: .stepCount) else { return }
let startDate = Calendar.current.startOfDay(for: Date())
let predicate = HKQuery.predicateForSamples(withStart: startDate, end: Date(), options: .strictEndDate)
var interval = DateComponents()
interval.day = 1
let query = HKStatisticsCollectionQuery(quantityType: sampleType, quantitySamplePredicate: predicate, options: [.cumulativeSum], anchorDate: startDate, intervalComponents: interval)
query.initialResultsHandler = { query,result,error in
if let myresult = result {
myresult.enumerateStatistics(from: startDate, to: Date()) { (statistic, value) in
if let count = statistic.sumQuantity() {
val = Int(count.doubleValue(for: HKUnit.count()))
}
}
}
}
healthStore.execute(query)
completion(val)
}
当我打印函数的完成处理程序时,它打印 0
而不是 Int(count.doubleValue(for: HKUnit.count()))
,函数内部设置了 val。任何关于为什么我得到 0
而不是 set val 的输入将不胜感激!
请注意 query.initialResultsHandler
是 异步的 并且您的代码将按以下顺序执行:
private func getSteps(completion: (Int) -> ()) {
// #1
var val: Int = 0
...
// #2
query.initialResultsHandler = { query,result,error in
// #5
if let myresult = result {
myresult.enumerateStatistics(from: startDate, to: Date()) { (statistic, value) in
if let count = statistic.sumQuantity() {
// #6
val = Int(count.doubleValue(for: HKUnit.count()))
}
}
}
// #7
}
// #3
healthStore.execute(query)
// #4
completion(val)
}
注意 #4 在 #6 之前执行。
解决办法是把completion
移到异步块里面:
private func getSteps(completion: (Int) -> ()) {
...
query.initialResultsHandler = { query,result,error in
if let myresult = result {
myresult.enumerateStatistics(from: startDate, to: Date()) { (statistic, value) in
if let count = statistic.sumQuantity() {
val = Int(count.doubleValue(for: HKUnit.count()))
}
}
}
completion(val) // <- move here
}
healthStore.execute(query)
}
我的这个函数有一个完成处理程序,该处理程序将在任务完成后返回,但从我得到的输出来看,它表明完成处理程序被认为已完成并在任务完成之前返回.
正在调用的函数:
private func getSteps(completion: (Int) -> ()) {
var val: Int = 0
guard let sampleType = HKObjectType.quantityType(forIdentifier: .stepCount) else { return }
let startDate = Calendar.current.startOfDay(for: Date())
let predicate = HKQuery.predicateForSamples(withStart: startDate, end: Date(), options: .strictEndDate)
var interval = DateComponents()
interval.day = 1
let query = HKStatisticsCollectionQuery(quantityType: sampleType, quantitySamplePredicate: predicate, options: [.cumulativeSum], anchorDate: startDate, intervalComponents: interval)
query.initialResultsHandler = { query,result,error in
if let myresult = result {
myresult.enumerateStatistics(from: startDate, to: Date()) { (statistic, value) in
if let count = statistic.sumQuantity() {
val = Int(count.doubleValue(for: HKUnit.count()))
}
}
}
}
healthStore.execute(query)
completion(val)
}
当我打印函数的完成处理程序时,它打印 0
而不是 Int(count.doubleValue(for: HKUnit.count()))
,函数内部设置了 val。任何关于为什么我得到 0
而不是 set val 的输入将不胜感激!
请注意 query.initialResultsHandler
是 异步的 并且您的代码将按以下顺序执行:
private func getSteps(completion: (Int) -> ()) {
// #1
var val: Int = 0
...
// #2
query.initialResultsHandler = { query,result,error in
// #5
if let myresult = result {
myresult.enumerateStatistics(from: startDate, to: Date()) { (statistic, value) in
if let count = statistic.sumQuantity() {
// #6
val = Int(count.doubleValue(for: HKUnit.count()))
}
}
}
// #7
}
// #3
healthStore.execute(query)
// #4
completion(val)
}
注意 #4 在 #6 之前执行。
解决办法是把completion
移到异步块里面:
private func getSteps(completion: (Int) -> ()) {
...
query.initialResultsHandler = { query,result,error in
if let myresult = result {
myresult.enumerateStatistics(from: startDate, to: Date()) { (statistic, value) in
if let count = statistic.sumQuantity() {
val = Int(count.doubleValue(for: HKUnit.count()))
}
}
}
completion(val) // <- move here
}
healthStore.execute(query)
}