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

Swift函数在if-else逻辑中无法返回正确的Bool值

问题分析与解决方案

问题根源:异步执行顺序问题

你的函数总是返回初始值(代码里初始设为true,你反馈总是返回false应该是测试时调整过初始值),核心原因是Firestore的getDocuments是异步操作:

  • 调用getDocuments后,系统会在后台线程发起网络请求,主线程不会等待请求完成,会直接执行后续的return busyResult,此时异步回调里的busyResult赋值逻辑还没触发。
  • 等网络请求完成后再修改busyResult,函数已经早就返回了,所以返回的永远是你一开始设置的初始值。

解决方案

方案1:使用闭包(Completion Handler)

把函数改成通过闭包返回结果,规避同步返回的局限性:

func checkBusyDates(busyDate: Date, completion: @escaping (Bool) -> Void) {
    let db = Firestore.firestore()
    
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "y-MM-dd"
    // 注意:如果Firestore存储的日期是UTC时区,这里要对应设置时区,避免匹配错误
    dateFormatter.timeZone = TimeZone(identifier: "UTC")
    let eventDate = dateFormatter.string(from: busyDate)
    
    db.collection("book").whereField("eventDate", isEqualTo: eventDate).getDocuments { snapshot, error in
        if let error = error {
            print("Document Error: ", error)
            completion(false) // 出错时返回false,可根据业务需求调整
            return
        }
        
        let isBusy = snapshot?.documents.isEmpty == false
        print(isBusy ? "Date is busy." : "Date is not busy.")
        completion(isBusy)
    }
}

// 调用示例
checkBusyDates(busyDate: Date()) { isBusy in
    // 在这里处理检查结果
    print("当前日期是否被占用:\(isBusy)")
}

方案2:使用Async/Await(Swift 5.5+)

如果你的项目支持Swift 5.5及以上(对应iOS 15+/macOS 12+等),可以用异步函数语法,代码更简洁直观:

func checkBusyDates(busyDate: Date) async -> Bool {
    let db = Firestore.firestore()
    
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "y-MM-dd"
    dateFormatter.timeZone = TimeZone(identifier: "UTC") // 匹配Firestore存储时区
    let eventDate = dateFormatter.string(from: busyDate)
    
    do {
        let snapshot = try await db.collection("book").whereField("eventDate", isEqualTo: eventDate).getDocuments()
        let isBusy = !snapshot.documents.isEmpty
        print(isBusy ? "Date is busy." : "Date is not busy.")
        return isBusy
    } catch {
        print("Document Error: ", error)
        return false // 出错时返回false,按需调整
    }
}

// 调用示例(需在异步上下文执行,比如Task)
Task {
    let isBusy = await checkBusyDates(busyDate: Date())
    print("当前日期是否被占用:\(isBusy)")
}

额外注意点

  • 时区匹配:确保DateFormatter的时区和Firestore中存储eventDate时使用的时区一致,否则会出现日期字符串不匹配的问题,导致检查结果错误。
  • 错误处理:根据实际业务需求调整错误情况下的返回逻辑,比如出错时可以返回nil或者抛出错误,而不是直接返回false。

内容的提问来源于stack exchange,提问作者Luboš Vrtík

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 15:18:14