为何未做任何代码改动时,原本正常运行的Swift程序JSON解码器返回nil?
JSONDecoder无代码改动突然返回nil的常见诱因
首先要做的事:把被吞掉的报错露出来
你现在用try?包着解码逻辑,所有真实的解码异常都会直接被转成nil,根本看不到到底是啥原因失败,这是排查的最大阻碍。把这部分代码改成显式捕获错误的写法,跑一次就能拿到精准的失败原因:
把原有的解码判断替换成下面的写法:
if let data = data { do { let decodedComments = try JSONDecoder().decode(CommentListing.self, from: data) DispatchQueue.main.async { let commentObjectsWrapper = decodedComments.data! let commentObjects = commentObjectsWrapper.children for commentObject in commentObjects { self.comments.append(commentObject.data!) } } } catch { print("解码失败具体原因:\(error)") } }
没有改动代码却突然解码失败的常见原因,按出现概率排序
- 你调用的Reddit匿名公开接口的返回结构发生了变化:比如字段改名、字段类型调整,甚至因为频繁请求被限流,直接返回了非JSON格式的429错误提示页、HTML格式的拦截页面,和你本地定义的Codable结构完全对不上,自然会解码失败
- 网络层返回了不符合预期的缓存内容:比如拿到了旧版本的接口响应、或者被中间网络节点篡改的返回数据,和当前的模型结构匹配不上
- 本地定义的Codable模型本身存在边界适配漏洞:比如之前所有请求刚好都拿到了非空的可选字段值,这次请求碰巧碰到了字段为空、或者值类型和定义不符的响应(比如被删除的评论会返回null的data字段),直接触发解码失败
- 代码里的强制解包隐患:哪怕解码暂时能过,后续直接用
!强制解包decodedComments.data、commentObject.data的写法,只要碰到接口返回null的场景,不仅会解码失败,还会直接触发崩溃
顺带提一下的现有实现问题
你现在每5秒轮询一次全量评论,既没有做重复数据去重,也没有处理接口返回的限流状态,高频的匿名请求很容易触发Reddit的反爬限制,进一步降低接口返回的成功率。
内容的提问来源于stack exchange,提问作者Mark Reggiardo
相关产品推荐
相关产品推荐

