gpt4 book ai didi

ios - 重建/重置核心数据时出错

转载 作者:可可西里 更新时间:2023-11-01 00:59:31 25 4
gpt4 key购买 nike

如果轻量级迁移失败,我将尝试重建核心数据数据堆栈,并将用户送回登录屏幕。我正在通过将一对多关系更改为一对一关系来对此进行测试。

起初,我在删除新的 persistentStoreCoordinator 后使用相同的 URL (storeURL);但是,我在 rebuildCoreData() 中的“try persistentStoreCoordinator.add...”行中收到一条错误消息,指出“无法两次添加同一商店”

其次,我决定通过附加“1”来更改新持久存储中的 url,使其变为 self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData1.sqlite")。这朝着正确的方向迈出了一步 - 还没有错误,我能够回到登录屏幕。但是,在登录后尝试进行第一次保存后,我收到错误“This NSPersistentStoreCoordinator has no persistent stores (schema mismatch or migration failure)”。它无法执行保存操作。'

我在这里做错了什么?

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
let options = [NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true]
var failureReason = "There was an error creating or loading the application's saved data."
do {
try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: options)
} catch {
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason

dict[NSUnderlyingErrorKey] = error as NSError
let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
self.rebuildCoreData()
}

return coordinator
}()

lazy var managedObjectContext: NSManagedObjectContext = {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
let coordinator = self.persistentStoreCoordinator
var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = coordinator
managedObjectContext.mergePolicy = NSRollbackMergePolicy //This policy discards in-memory state changes for objects in conflict. The persistent store’s version of the objects’ state is used

return managedObjectContext
}()

// MARK: - Tearing down core data stack and rebuilding it in the case that a lightweight migration fails
func rebuildCoreData() {

let storeURL = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
do {
try NSFileManager.defaultManager().removeItemAtURL(storeURL)
} catch {
print(error)
abort()
}

for object in managedObjectContext.registeredObjects {
managedObjectContext.deleteObject(object)
}

do {
try persistentStoreCoordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: [NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true])
} catch {
print(error)
abort()
}

print("successfully rebuilt core data")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateInitialViewController()
self.window?.rootViewController?.presentViewController(controller!, animated: false, completion: nil)
}

更新 - 在 catch block 中更改文件删除和编辑持久存储协调器逻辑

 lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
var coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
let options = [NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true]
var failureReason = "There was an error creating or loading the application's saved data."
do {
try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: options)
} catch {

// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason

dict[NSUnderlyingErrorKey] = error as NSError
let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")

//rebuilds core data
coordinator = self.rebuildCoreData(coordinator)
}

return coordinator
}()

新的 rebuildCoreData 代码:

  // MARK: - Tearing down core data stack and rebuilding it in the case that a lightweight migration fails
func rebuildCoreData(coordinator: NSPersistentStoreCoordinator) -> NSPersistentStoreCoordinator {

let persistentStoreParentPath = self.applicationDocumentsDirectory.path
let fileEnumerator = NSFileManager.defaultManager().enumeratorAtPath(persistentStoreParentPath!)
while let path = fileEnumerator?.nextObject() as? String {
if path.hasPrefix("SingleViewCoreData.sqlite") || path.hasPrefix(".SingleViewCoreData.sqlite") {
let pathToDelete = (persistentStoreParentPath! as NSString).stringByAppendingPathComponent(path)
do {
try NSFileManager.defaultManager().removeItemAtPath(pathToDelete)
}
catch _ {
// Handle error removing file
}
}
}

for object in managedObjectContext.registeredObjects {
managedObjectContext.deleteObject(object)
}

do {
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: [NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true])
} catch {
print(error)
abort()
}

print("successfully rebuilt core data")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateInitialViewController()
self.window?.rootViewController?.presentViewController(controller!, animated: false, completion: nil)

return coordinator
}

最佳答案

CoreData在较新的 iOS 版本中,stack 不包含单个文件。您可以创建自己的 CoreData堆栈并检查文件系统以具体查看文件的名称(我记得还有一个 .shm 和一个 .wal 文件)。话虽如此,当我清除文件时,我通常使用 NSFileManager枚举我的存储文件的父路径中的对象并删除前缀为 <StoreFileName>.sqlite 的任何内容和 .<StoreFileName>.sqlite .您也可以考虑将您的商店文件放在一个子目录中,然后只删除整个子目录。

let persistentStoreParentPath = self.applicationDocumentsDirectory.path
let fileEnumerator = NSFileManager.defaultManager().enumeratorAtPath(persistentStoreParentPath)
while let path = fileEnumerator?.nextObject() as? String {
if path.hasPrefix("SingleViewCoreData.sqlite") || path.hasPrefix(".SingleViewCoreData.sqlite") {
let pathToDelete = (persistentStoreParentPath as NSString).stringByAppendingPathComponent(path)
do {
try NSFileManager.defaultManager().removeItemAtPath(pathToDelete)
}
catch _ {
// Handle error removing file
}
}
}

不过,您上面的代码还有一些其他问题需要考虑。您正在调用 rebuildCoreData()从初始化 persistentStoreCoordinator 的闭包内部, 但你使用 persistentStoreCoordinatorrebuildCoreData()直接和间接(通过访问 managedObjectContext ,它使用 persistentStoreCoordinator )。

关于ios - 重建/重置核心数据时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37314254/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com