重置 CoreData 持久存储 [英] Reset a CoreData persistent store

查看:27
本文介绍了重置 CoreData 持久存储的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上,我要做的是清除 CoreData 持久存储中的所有数据,然后导入新数据.你会怎么做?似乎最简单的解决方案是调用 [NSPersistentStoreCoordinator removePersistentStore:error:] 然后删除文件.这是可用的最佳实践吗?它是线程安全的吗?

Basically, what I'm trying to do is to wipe out all data in my CoreData persistent store, then import new data. How would you do this? It seems that the simplest solution is call [NSPersistentStoreCoordinator removePersistentStore:error:] and then remove the file. Is that the best practice available? Is it thread-safe?

非常感谢,

问题 0.1:是

我正在尝试更新 CoreData 持久存储中的数据.我的用户正在查看带有统计数据的表格视图.我想通过删除所有现有数据然后导入新数据来更新应用程序.我想显示一个进度视图来告诉用户应用程序没有挂起.

I am trying to update the data in a CoreData persistent store. My user is seeing a table view with statistical data. I want to update the application by deleting all existing data, then importing new data. I would like to show a progress view to tell the user that the application is not hanging.

我在我的 AppDelegate 中添加了以下 resetPersistentStore 方法(persistentStoreCoordinator 仅供参考):

I have added the following resetPersistentStore method in my AppDelegate (persistentStoreCoordinatoris given for reference):

// ...
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
// ...

/**
 Returns the persistent store coordinator for the application.
 If the coordinator doesn't already exist, it is created and the application's store added to it.
 */
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }

    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: kPersistentStoreFilename]];

    NSError *error = nil;
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }    

    return persistentStoreCoordinator;
}

/**
 * Will remove the persistent store
 */
- (NSPersistentStoreCoordinator *)resetPersistentStore {
    NSError *error;

    [managedObjectContext lock];

    // FIXME: dirty. If there are many stores...
    NSPersistentStore *store = [[persistentStoreCoordinator persistentStores] objectAtIndex:0];

    if (![persistentStoreCoordinator removePersistentStore:store error:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }  

    // Delete file
    if (![[NSFileManager defaultManager] removeItemAtPath:store.URL.path error:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    } 

    // Delete the reference to non-existing store
    [persistentStoreCoordinator release];
    persistentStoreCoordinator = nil;

    NSPersistentStoreCoordinator *r = [self persistentStoreCoordinator];
    [managedObjectContext unlock];

    return r;
}

然后在我看来我这样做(在另一个线程中,因为我使用的是 MBProgressHUD:

Then in my view I do (in another thread since I am using MBProgressHUD:

PatrimoineAppDelegate *appDelegate = (PatrimoineAppDelegate *)[[UIApplication sharedApplication] delegate]; 
// Delete everything
[appDelegate resetPersistentStore];

然后我得到一个 EXC_BAD_ACESS...

And I get an EXC_BAD_ACESS...

我不太了解 CoreData 或多线程,也许我在做一个明显的错误...

I do not know CoreData or multithreading very well, maybe I'm doing an evident error...

推荐答案

如果您的目标是清空数据存储并使用新信息重新加载它,您最好使用 NSManagedObjectContext 的 reset 然后加载新数据.

If your goal is to empty the data store and reload it with new information, you may be better off using NSManagedObjectContext's reset and then loading in new data.

来自 NSManagedObjectContext 的文档

上下文总是有一个父"持久存储协调器,它提供模型并将请求分派到包含数据的各种持久存储.没有协调器,上下文就不能完全发挥作用.上下文的协调器提供托管对象模型并处理持久性.从外部存储中获取的所有对象都与一个全局标识符(NSManagedObjectID 的一个实例)一起注册在上下文中,该标识符用于向外部存储唯一标识每个对象.

A context always has a "parent" persistent store coordinator which provides the model and dispatches requests to the various persistent stores containing the data. Without a coordinator, a context is not fully functional. The context’s coordinator provides the managed object model and handles persistency. All objects fetched from an external store are registered in a context together with a global identifier (an instance of NSManagedObjectID) that’s used to uniquely identify each object to the external store.

删除持久存储并使用与存储关联的托管对象上下文可能是导致错误的原因.

Removing the persistent store and using the managed object context associated with the store is probably the cause of the error.

这篇关于重置 CoreData 持久存储的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆