Swift深度嵌套字典的安全写入方法及数据结构合理性探讨
问题解答
一、数据结构的合理性
你的三层字典结构完全贴合业务逻辑——按「图片ID→画质级别→任务优先级」的层级映射到任务,逻辑清晰,读取时用可选链也确实方便。这种写法的繁琐只是Swift值类型特性带来的小问题,不是结构设计不合理,除非你的业务场景里有更适合的聚合方式。
二、更流畅的写入方式
方法1:用空合运算符代替强制解包
把原来判断nil再初始化的逻辑,换成空合运算符(??)来获取或创建嵌套字典,全程不用冒风险强制解包:
// 取出当前图片ID对应的画质字典,不存在就新建空字典 var qualityMap = loadingTasks[id] ?? [:] // 取出当前画质对应的优先级字典,不存在就新建空字典 var priorityMap = qualityMap[level] ?? [:] // 给对应优先级赋值任务 priorityMap[priority] = task // 把修改后的字典逐层存回原字典 qualityMap[level] = priorityMap loadingTasks[id] = qualityMap
方法2:利用Swift的默认下标语法(Swift 4+)
Swift 4之后支持带默认值的字典下标,可以简化嵌套字典的创建逻辑,不过要注意字典是值类型,得用可变变量中转一下确保修改生效:
// 获取或创建图片ID对应的画质字典 var qualityMap = loadingTasks[id, default: [:]] // 直接通过默认下标创建优先级字典并赋值 qualityMap[level, default: [:]][priority] = task // 把修改后的画质字典存回原字典 loadingTasks[id] = qualityMap
方法3:用组合键重构字典
如果你的业务里大部分操作都是同时指定「图片ID+画质+优先级」三个维度,很少单独按层级批量操作,可以把这三个字段封装成一个可哈希的结构体当字典键:
// 定义组合键结构体,必须遵循Hashable协议 struct TaskIdentifier: Hashable { let imageId: ImageId let quality: Quality let priority: TaskPriority } // 把原三层字典改成单层字典 private var loadingTasks: [TaskIdentifier: Task<Void, Error>] = [:] // 写入时直接赋值,一步到位 loadingTasks[TaskIdentifier(imageId: id, quality: level, priority: priority)] = task
这种写法写入超级简洁,但要是需要批量获取某个图片ID下的所有任务,就得遍历字典过滤键,比如:
let tasksForImage = loadingTasks.filter { $0.key.imageId == targetId }.values
要不要用这种方式,看你日常业务操作的侧重点。
内容的提问来源于stack exchange,提问作者CalebK
相关产品推荐
相关产品推荐

