der*_*ida 5 core-data ios swift
我们正在通过 Citrix Secure Hub 运行应用程序,似乎有时会出现回滚并丢失 CoreData 中的一些数据。
据我了解,CoreData 拥有类似所有对象的工作副本之类的东西,有时它会尝试将其保留在文件系统上。
我们尝试模拟该行为,但没有成功,我们在测试环境中找不到任何数据丢失或回滚的数据。
那么有没有办法强制 iOS 将当前的“工作副本”写入磁盘,以防止在使用过多内存(甚至可能崩溃)时丢失任何数据?我们在之后调用我们的保存函数
正如我们已经发现的:
我们没有使用:
func applicationWillResignActive(_ application: UIApplication) {
print("applicationWillResignActive")
}
Run Code Online (Sandbox Code Playgroud)
要保存上下文,这可能是一个问题(我们已经在每个创建的对象之后保存上下文)?
目前,当上下文无法保存时,我们并没有真正处理问题,是否有任何建议如何在生产环境中处理该问题?也许应用程序崩溃以防止用户因数据丢失而苦苦挣扎,这是一件好事吗?
编辑:这是使用的核心数据处理程序:
import Foundation
import CoreData
let context = CoreDataManager.shared.managedObjectContext
func saveContext(_ completion: (() -> Void)? = nil) {
CoreDataManager.shared.save(completion)
}
func saveContextSync() {
CoreDataManager.shared.saveSync()
}
class CoreDataManager: NSObject {
static let shared = CoreDataManager()
lazy var managedObjectContext: NSManagedObjectContext = {
var managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = persistentStoreCoordinator
return managedObjectContext
}()
Run Code Online (Sandbox Code Playgroud)
我们的保存功能:
@objc func save(_ completion: (() -> Void)?) {
saveAsync(completion)
}
func saveAsync(_ completion: (() -> Void)?) {
func save() {
context.perform {
do { try context.save() }
catch {
// HERE WE NEED TO HANDLE IT FOR A PRODUCTIVE ENVIRONMENT
}
completion?()
}
}
if Thread.isMainThread {
save()
} else {
DispatchQueue.main.async {
save()
}
}
}
func saveSync() {
func save() {
context.performAndWait {
do { try context.save() }
catch { print(error)
// TRY TO REPRODUCE MEMORY LOSS APP TO SEE WHAT HAPPENS
abort()
}
}
}
if Thread.isMainThread {
save()
} else {
DispatchQueue.main.sync {
save()
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑2:Objective C中的这个问题应该非常相似:
编辑3:似乎没有崩溃,一些用户告诉我他们正在添加数据,然后只需按主页按钮,几个小时后,最后一个“任务”的数据就会丢失。
可能的原因有以下三个。
核心数据通常希望以单一同步方式完成写入。如果您同时以多种方式写入同一个对象(即使它们接触不同的属性并且不严格冲突),这将是合并冲突。您可以设置合并策略(默认情况下,该值为“错误” - 意味着不应用更改),但这确实是一个糟糕的解决方案,因为您会告诉核心数据默默地丢失信息。请参阅NSPersistentContainer 并发性以保存到核心数据,以进行设置以防止合并冲突。
如果您正确设置核心数据,则不会发生这种情况。将核心数据设置为仅从“viewContext”读取并以单一同步方式写入的正确方法。每次写入都在单个原子块中完成,并且 UI 仅在保存后更新。如果您显示的信息来自未保存到磁盘的上下文,这可能会出现问题。例如,您的应用程序似乎仅使用单个主线程上下文进行读取和写入。对该上下文进行更改而不调用保存将使应用程序处于仅在内存中而不是在磁盘上进行重大更改的状态。
这是迄今为止最罕见的事件,但有些用户的磁盘确实已满。如果发生这种情况,您将无能为力。磁盘上物理上没有剩余空间。一般来说,正确的做法是告诉用户然后就这样。
如果不了解更多关于您的特定设置的信息,很难确定您的问题是什么。我会推荐以下设置:
NSPersistentContainerviewContext而不能写入。这应该可以解决除第三个问题之外的所有问题。
| 归档时间: |
|
| 查看次数: |
1372 次 |
| 最近记录: |