能否创建无需保存到Core Data的NSManagedObject实例以复用配置视图?
核心问题解答
你完全可以创建永久不需要持久化到Core Data的NSManagedObject实例,你之前遇到的Multiple NSEntityDescriptions报错和方案本身无关,是因为你创建独立内存上下文时重复加载了Core Data模型文件,导致同一个JournalSettings类对应了多个实体描述实例产生歧义。
正确实现临时Core Data实例的方案
复用你现有主Core Data栈的NSManagedObjectModel创建纯内存的独立上下文,完全和主持久化存储隔离,既可以生成符合要求的JournalSettings实例,也完全不会污染主存储:
// 复用全局已加载的Core Data模型,避免重复加载导致的实体冲突 let sharedModel = mainPersistentContainer.managedObjectModel let tempCoordinator = NSPersistentStoreCoordinator(managedObjectModel: sharedModel) // 配置纯内存存储,所有操作不会写入磁盘 try? tempCoordinator.addPersistentStore(type: .inMemory, at: nil, options: nil) // 创建临时上下文,和主Core Data栈完全隔离 let tempContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType) tempContext.persistentStoreCoordinator = tempCoordinator // 从UserDefaults读取默认配置,生成临时JournalSettings实例 let defaultSettings = JournalSettings(context: tempContext) defaultSettings.fontSize = UserDefaults.standard.double(forKey: "default_font_size") // 其他属性赋值同理
这个上下文你永远不需要调用save()方法,就算误调用也只会把数据存在内存中,不会同步到主上下文或者写入磁盘,完全满足你的需求。
备选方案对比
你提到的两个方案都不是最优解:
- 方案1(默认配置迁移到Core Data):虽然可以运行,但全局轻量默认配置本身就更适合存在UserDefaults,为了适配视图修改存储方案没有必要。
- 方案2(重写新视图):会产生大量冗余代码,后续修改设置项需要同时维护两个视图,维护成本极高。
更优解:协议解耦(推荐)
如果不想额外维护临时Core Data上下文,你可以通过协议抽象解耦视图和数据模型,不需要修改现有视图逻辑即可兼容两种数据源:
- 抽离
JournalSettingsView用到的所有属性为公共协议:
protocol JournalSettingsRepresentable { var fontSize: Double { get set } var defaultTitle: String { get set } var themeType: Int { get set } // 其他所有视图用到的属性 }
- 让现有Core Data的
JournalSettings类遵守该协议:
extension JournalSettings: JournalSettingsRepresentable {}
- 创建默认配置模型,直接对接UserDefaults,同样遵守该协议:
struct DefaultJournalSettings: JournalSettingsRepresentable { var fontSize: Double { get { UserDefaults.standard.double(forKey: "default_font_size") } set { UserDefaults.standard.set(newValue, forKey: "default_font_size") } } // 其他属性实现同理,直接读写UserDefaults即可 }
- 将
JournalSettingsView的入参类型从JournalSettings修改为any JournalSettingsRepresentable,无需修改视图内部的交互逻辑,即可同时兼容Core Data实例和默认配置实例。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

