Xcode开发每日名言App时间戳异常、索引不递增及空白屏问题咨询
问题修复方案
完整修改后代码
// 建议定义常量存UserDefaults的key,避免拼写错误 private let kLastQuoteDayKey = "lastQuoteTimestamp" private let kQuoteIndexKey = "currentQuoteIndex" func displayQuote() { // 显式指定时区为用户当前时区,避免项目全局修改日历配置导致时区异常 var calendar = Calendar.current calendar.timeZone = .current let todayStart = calendar.startOfDay(for: Date()) let storedDay = UserDefaults.standard.object(forKey: kLastQuoteDayKey) as? Date // 从持久化存储读取当前名言索引,不存在时默认返回0 var currentIndex = UserDefaults.standard.integer(forKey: kQuoteIndexKey) // 首次启动或已进入新的一天 if storedDay == nil || calendar.dateComponents([.day], from: storedDay!, to: todayStart).day ?? 0 >= 1 { // 非首次启动才递增索引 if storedDay != nil { currentIndex += 1 // 可选配置:名言全部展示完后循环回到第一条 if currentIndex >= quotes.count { currentIndex = 0 } } // 持久化更新索引和当日时间戳 UserDefaults.standard.set(currentIndex, forKey: kQuoteIndexKey) UserDefaults.standard.set(todayStart, forKey: kLastQuoteDayKey) } // 无论是否是新的一天,都给文本控件赋值,解决空白屏问题 textView.text = quotes[currentIndex] }
逐个问题修复说明
1. 时区问题
- 原因:
Date类型本身不携带时区属性,打印时显示UTC是系统默认输出格式的问题,startOfDay的计算逻辑依赖日历的时区配置,部分项目可能存在全局修改Calendar.current参数的场景,导致计算时用了UTC时区。 - 修复:显式初始化Calendar并指定时区为
.current,同时将时间间隔判断改为用系统dateComponents计算天差,避免夏令时、闰秒等特殊场景下除以24小时的计算方式出错。
2. index不递增问题
- 原因:原代码中的
index是内存变量,App重启后就会重置为0,没有做持久化存储,即便触发了更新逻辑,下次启动还是会回到初始值。 - 修复:把index也存入
UserDefaults,每次启动先读取持久化的index值,只有触发新一天更新逻辑时再递增后回存。
3. 第二次启动空白屏问题
- 原因:原代码仅在满足「新的一天」的条件分支里才给
textView.text赋值,第二次启动时时间间隔还没到24小时,不会走该分支,文本控件就没有内容。 - 修复:把文本赋值逻辑移到if判断外部,无论是不是新的一天,都用当前的index给文本控件赋值,仅在新的一天时更新index和存储的时间戳。
内容的提问来源于stack exchange,提问作者VMT
相关产品推荐
相关产品推荐

