
1) 【一句话结论】:采用“多级缓存+Core Data(或SQLite)+合理数据模型”方案,通过实体拆分(如Report、Image、DataModel)、索引优化、分页加载和版本控制,实现离线可用、数据一致且查询高效。
2) 【原理/概念讲解】:
数据模型设计是核心,需将质检报告拆分为实体(如Report存储元数据:ID、创建时间、图片路径、数据ID;Image存储图片路径或数据(图片大则存本地文件系统);DataModel存储结构化检测数据(如JSON解析后的键值对))。
NSCache)+本地文件系统(路径存数据库),检测数据用Core Data预取缓存;离线时优先从本地数据库读取,网络同步时通过事务更新。数据一致性通过事务(save方法)和锁(SQLite行级锁)保证,版本控制处理数据结构变更或冲突。3) 【对比与适用场景】:
| 特性 | Core Data | SQLite |
|---|---|---|
| 定义 | Apple的对象图管理框架,自动持久化对象关系 | 轻量级关系型数据库,手动SQL操作 |
| 特性 | 自动对象关联、版本控制、快照、事务 | 手动SQL,支持复杂查询(JOIN等),体积小 |
| 使用场景 | 对象关系复杂,需自动管理(如iOS原生应用) | 需要复杂查询、自定义SQL,或与现有数据库兼容 |
| 注意点 | 模型变更需迁移,性能受对象图管理影响 | 需手动处理事务、锁,数据模型需自己设计 |
4) 【示例】:
用Core Data设计实体:
Report(质检报告):@property (NSManaged) NSNumber *id; @property (NSManaged) NSDate *createdAt; @property (NSManaged) NSManagedObject *image; @property (NSManaged) NSManagedObject *dataModel;Image(图片):@property (NSString *) path; @property (NSData *) data;(图片数据存文件系统,路径存数据库)DataModel(检测数据):@property (NSString *) key; @property (NSString *) value;(存储结构化数据,如JSON解析后)查询示例(获取最近10条报告):
let context = persistentContainer.viewContext
let fetchRequest = Report.fetchRequest()
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "createdAt", ascending: false)]
fetchRequest.fetchLimit = 10
let reports = try context.fetch(fetchRequest)
图片缓存:图片路径从Image实体获取,用NSCache缓存图片数据(避免重复加载)。
5) 【面试口播版答案】:
面试官您好,对于存储大量质检报告(含图片和检测数据),我会采用“多级缓存+Core Data+合理数据模型”方案。首先,数据模型设计上,将报告拆分为三个实体:Report(存储元数据,如ID、时间、图片路径、数据ID)、Image(存储图片路径或数据,图片大则存本地文件系统)、DataModel(存储结构化检测数据,如JSON解析后)。这样既分离了图片和结构化数据,又便于查询。缓存策略上,图片用内存缓存(如NSCache)+本地文件系统,检测数据用Core Data的缓存(预取最近访问数据),离线时优先从本地数据库读取,网络同步时通过事务更新本地数据。数据一致性通过Core Data的事务(save方法)和版本控制(模型版本)保证,确保并发操作时数据不冲突。比如,当用户离线查看报告时,系统从Core Data中读取Report和关联的Image、DataModel,图片通过本地文件系统加载,检测数据从DataModel中解析,实现离线可用。网络恢复后,同步服务器数据更新本地数据库,通过事务保证数据一致性。
6) 【追问清单】:
createdAt、id建索引)、分页查询(fetchRequest的fetchLimit和offset)、预取策略(NSFetchedResultsController的预取),减少内存占用和查询时间。NSCache缓存图片数据(避免重复加载),设置缓存策略(如内存LRU),图片路径存数据库,加载时先检查缓存,再从文件系统读取。7) 【常见坑/雷区】: