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
相关产品推荐
相关产品推荐

