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

无法初始化nil Date:iOS App首次运行JSON更新失败问题排查

问题

  • 用于标记JSON更新时间的storedDate初始化存在异常:App首次运行时无法触发JSON更新,后续更新流程正常。为触发首次启动的即时更新,尝试将初始日期设为旧日期,但该逻辑从未生效。
  • 不愿使用可选Date配合??的处理方式(需在多处编写合并逻辑,且编造默认日期不符合编码规范),希望找到更优的Date初始化方案。
  • 调试发现:首次运行且UserDefaults中无存储日期时,进入初始化器前storedDate已被设为当前日期,设置旧日期的逻辑未被执行。
  • 初始化器中let storedDate = UserDefaults...行出现「未使用变量」警告,但明明在逻辑中用到了该变量,不知如何消除警告。

解决方案

问题根源

  1. 局部变量遮蔽类属性:初始化器中定义的let storedDate是局部变量,并未给类的storedDate属性赋值,导致类属性始终保持默认的当前日期;局部变量后续未被实际使用,因此触发警告。
  2. 类属性提前初始化:类的storedDate属性设置了默认值Date(),在初始化器执行前就已完成赋值,覆盖了初始化器中的自定义逻辑。

修复步骤

  1. 移除类属性的默认值,在初始化器中直接为类的storedDate属性赋值。
  2. 避免定义局部变量storedDate,直接操作类属性,同时同步到UserDefaults。
  3. 使用安全的可选绑定读取UserDefaults中的日期,避免强制解包引发崩溃。

修正后的代码

@Observable final class GetRatesModel {
    
    @ObservationIgnored var storedDate: Date // 移除默认值
    
    init() {
        // 安全读取UserDefaults中的日期
        if let savedDate = UserDefaults.standard.object(forKey: StorageKeys.upd.rawValue) as? Date {
            self.storedDate = savedDate
        } else {
            // 首次启动时设置前一天的日期,比硬编码时间戳更清晰可靠
            let oldDate = Calendar.current.date(byAdding: .day, value: -1, to: Date.now)!
            self.storedDate = oldDate
            UserDefaults.standard.setValue(oldDate, forKey: StorageKeys.upd.rawValue)
        }
    }
    
    @MainActor func checkForUpdates(baseCur: String) async throws {
        // 比较日期是否为同一天
        if !Calendar.current.isDate(Date.now, equalTo: storedDate, toGranularity: .day) {
            print("getting data")
            
            let stored8601 = storedDate.formatted(.iso8601.year().month().day().dateSeparator(.dash))
            if stored8601 != JsonDate {
                // 更新日期时同步类属性和UserDefaults
                self.storedDate = Date.now
                UserDefaults.standard.setValue(self.storedDate, forKey: StorageKeys.upd.rawValue)
                
                // ... 后续JSON更新逻辑
            }
        }
    }
}

额外说明

  • 在checkForUpdates方法中更新日期时,需同时修改类的storedDate属性和UserDefaults,保证两者状态同步。
  • 用Calendar生成旧日期比硬编码时间戳更易读,也能避免因时间单位(秒/毫秒)误解导致的逻辑错误。

内容的提问来源于stack exchange,提问作者Galen Smith

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 21:27:44