You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift变量未更新问题:如何让函数返回修改后的returnVal?

问题分析与解决

你的问题核心是异步操作的执行顺序:makeQuery是异步方法(HealthKit查询在后台线程执行,通过逃逸闭包返回结果),而RecieveActivitySummary是同步返回值的函数。函数执行时会先跑完return returnVal,之后异步闭包才会触发修改returnVal,所以返回的自然是初始的空对象。

解决方法:把RecieveActivitySummary改成异步回调形式

同步函数无法等待异步任务完成再返回结果,所以必须将RecieveActivitySummary改为通过闭包回调返回HKActivitySummary,而不是直接返回值。

修改后的代码

// 改成带逃逸闭包的异步函数
func receiveActivitySummary(completion: @escaping (HKActivitySummary) -> Void) {
    self.makeQuery() { (summary) in
        // 拿到结果后通过闭包返回
        completion(summary)
        print(summary) // 这里打印的是带数据的对象
    }
}

// 原makeQuery函数可以保持不变(如果没有其他问题的话)
func makeQuery(completion: @escaping (_ summary : HKActivitySummary) -> ()) {
    let calendar = NSCalendar.current
    let endDate = Date()
    
    guard let startDate = calendar.date(byAdding: .day, value: 0, to: endDate) else {
        fatalError("error")
    }
    
    let units: Set<Calendar.Component> = [.day, .month, .year, .era]
    
    var startDatecomps = calendar.dateComponents(units, from: startDate)
    startDatecomps.calendar = calendar
    
    var endDatecomps = calendar.dateComponents(units, from: endDate)
    endDatecomps.calendar = calendar
    
    let summariesWithinRange = HKQuery.predicate(forActivitySummariesBetweenStart: startDatecomps, end: endDatecomps)
    
    let query = HKActivitySummaryQuery(predicate: summariesWithinRange) {
        (sample, results, error) -> Void in
        if let results = results {
            var summary = results[0]
            completion(summary)
        }
    }
    healthstore.execute(query)
}

调用方式

// 调用时通过闭包接收结果
receiveActivitySummary { summary in
    // 在这里处理拿到的HKActivitySummary对象
    print("拿到的结果:\(summary)")
}

额外提醒

  • 注意处理makeQuery中可能的错误情况(比如results为空、error不为空的情况),避免崩溃。可以在HKActivitySummaryQuery的回调里加上错误判断:
let query = HKActivitySummaryQuery(predicate: summariesWithinRange) {
    (sample, results, error) -> Void in
    if let error = error {
        // 处理错误,比如打印错误信息或者通过闭包返回错误
        print("查询失败:\(error.localizedDescription)")
        return
    }
    guard let results = results, !results.isEmpty else {
        print("没有找到活动数据")
        return
    }
    var summary = results[0]
    completion(summary)
}

内容的提问来源于stack exchange,提问作者Eddie Gabriel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 12:18:08