您知道删除Core Data中存储的所有条目的方法吗?我的架构应该保持不变;我只想将其重置为空白。
编辑
我希望以编程方式实现这一点,以便用户可以轻松点击“重置”按钮。
您知道删除Core Data中存储的所有条目的方法吗?我的架构应该保持不变;我只想将其重置为空白。
编辑
我希望以编程方式实现这一点,以便用户可以轻松点击“重置”按钮。
您仍然可以使用NSFileManager:removeItemAtPath:方法以编程方式删除文件。
NSPersistentStore *store = ...;
NSError *error;
NSURL *storeURL = store.URL;
NSPersistentStoreCoordinator *storeCoordinator = ...;
[storeCoordinator removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtPath:storeURL.path error:&error];
然后,只需添加持久存储以确保重新创建。以编程方式遍历每个实体的操作较慢且容易出错。这种方式的使用场景是如果您想删除某些实体而不删除其他实体。但是,您仍然需要确保保留引用完整性,否则无法保存更改。只需删除存储并重新创建即可快速安全地完成,当然可以在运行时以编程方式完成。allowsExternalBinaryDataStorage
或Store in External Record File
),仅删除storeURLs指向的文件是不够的。你会留下外部记录文件。由于这些外部记录文件的命名方案不是公开的,因此我尚无通用解决方案。 - an0你可以删除SQLite文件,但我选择通过逐个清除表的方法来实现:
- (void) deleteAllObjects: (NSString *) entityDescription {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityDescription inManagedObjectContext:_managedObjectContext];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *items = [_managedObjectContext executeFetchRequest:fetchRequest error:&error];
[fetchRequest release];
for (NSManagedObject *managedObject in items) {
[_managedObjectContext deleteObject:managedObject];
DLog(@"%@ object deleted",entityDescription);
}
if (![_managedObjectContext save:&error]) {
DLog(@"Error deleting %@ - error:%@",entityDescription,error);
}
}
我之所以选择逐个表进行操作,是因为这样可以在编程过程中确认删除表内容是明智的,并且没有任何重要数据需要保留。
这种方法比直接删除文件慢得多,如果这种方法太慢,我会改用删除文件的方式。
使用NSBatchDeleteRequest
删除实体中所有对象,无需将它们加载到内存中或迭代处理。
// create the delete request for the specified entity
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = MyEntity.fetchRequest()
let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
// get reference to the persistent container
let persistentContainer = (UIApplication.shared.delegate as! AppDelegate).persistentContainer
// perform the delete
do {
try persistentContainer.viewContext.execute(deleteRequest)
} catch {
print(error.localizedDescription)
}
这段代码已经更新为iOS 10和Swift 3。如果您需要支持iOS 9,请参见此问题。
来源:
moc.performBlockAndWait({ () -> Void in
... })
中。 - SwiftArchitect我写了一个clearStores
方法,它会遍历每个存储库,从协调器和文件系统中删除它(出于错误处理的考虑)。
NSArray *stores = [persistentStoreCoordinator persistentStores];
for(NSPersistentStore *store in stores) {
[persistentStoreCoordinator removePersistentStore:store error:nil];
[[NSFileManager defaultManager] removeItemAtPath:store.URL.path error:nil];
}
[persistentStoreCoordinator release], persistentStoreCoordinator = nil;
这个方法是在coreDataHelper
类中的,它负责(除了其他事情之外)在持久存储为nil时创建它。
我在HomeViewController类的按钮事件中删除了所有核心数据:
这篇文章帮助了我很多,所以我想做出贡献。
-(IBAction)buttonReset:(id)sender
{
NSLog(@"buttonReset Pressed");
//Erase the persistent store from coordinator and also file manager.
NSPersistentStore *store = [self.persistentStoreCoordinator.persistentStores lastObject];
NSError *error = nil;
NSURL *storeURL = store.URL;
[self.persistentStoreCoordinator removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:&error];
NSLog(@"Data Reset");
//Make new persistent store for future saves (Taken From Above Answer)
if (![self.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
// do something with the error
}
}
注意,为了调用self.persistentStoreCoordinator,我在Home View Controller中声明了一个属性。(不必担心我用于保存和加载的managedObjectContext。)@property (nonatomic, retain) NSManagedObjectContext * managedObjectContext;
@property (nonatomic, retain) NSPersistentStoreCoordinator * persistentStoreCoordinator;
然后在AppDelegate的ApplicationDidFinishLaunching方法下面创建HomeViewController后面我有这样一行代码:
homeViewController = [[HomeViewController alloc] initWithNibName:@"HomeViewController" bundle:nil];
homeViewController.managedObjectContext = self.managedObjectContext;
homeViewController.persistentStoreCoordinator = self.persistentStoreCoordinator;
iOS9+,Swift 2
删除所有实体中的所有对象
func clearCoreDataStore() {
let entities = managedObjectModel.entities
for entity in entities {
let fetchRequest = NSFetchRequest(entityName: entity.name!)
let deleteReqest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
do {
try context.executeRequest(deleteReqest)
} catch {
print(error)
}
}
}
MagicalRecord可以让这个过程变得非常容易。
[MyCoreDataObject MR_truncateAll];
MR_truncateAll
? - fatuhoku[对于寻求更新回复的悬赏问题的迟到回答]
经过查看之前的答案,
但是有一种不同的、类似的方法可以删除持久性存储,它确实起作用。关键是将持久存储文件放在自己的子目录中,该子目录不包含任何其他内容。不要只把它放在文档目录(或其他地方),而是为持久存储创建一个新的子目录。该目录的内容最终会成为持久存储文件、日志文件和外部二进制文件。如果您想清除整个数据存储,请删除该目录,它们都将消失。
在设置持久存储时,您可以这样做:
NSURL *storeDirectoryURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"persistent-store"];
if ([[NSFileManager defaultManager] createDirectoryAtURL:storeDirectoryURL
withIntermediateDirectories:NO
attributes:nil
error:nil]) {
NSURL *storeURL = [storeDirectoryURL URLByAppendingPathComponent:@"MyApp.sqlite"];
// continue with storeURL as usual...
}
当你想要移除存储时,
[[NSFileManager defaultManager] removeItemAtURL:storeDirectoryURL error:nil];
这将递归地删除自定义子目录及其中的所有Core Data文件。
仅当您的持久存储不在与其他重要数据相同的文件夹中时,此方法才有效。例如文档目录,其中可能包含其他有用的东西。如果您处于这种情况,则可以通过查找要保留的文件并删除其他所有文件来达到相同的效果。类似于:
NSString *docsDirectoryPath = [[self applicationDocumentsDirectory] path];
NSArray *docsDirectoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:docsDirectoryPath error:nil];
for (NSString *docsDirectoryItem in docsDirectoryContents) {
// Look at docsDirectoryItem. If it's something you want to keep, do nothing.
// If it's something you don't recognize, remove it.
}
这种方法可能存在错误风险。你必须确保你知道每一个想要保留的文件,否则你可能会删除重要的数据。另一方面,你可以删除外部二进制文件,而不必知道用于存储它们的文件/目录名称。
这是一个清除 Core Data 的综合解决方案。
- (void)deleteAllObjectsInCoreData
{
NSArray *allEntities = self.managedObjectModel.entities;
for (NSEntityDescription *entityDescription in allEntities)
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entityDescription];
fetchRequest.includesPropertyValues = NO;
fetchRequest.includesSubentities = NO;
NSError *error;
NSArray *items = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (error) {
NSLog(@"Error requesting items from Core Data: %@", [error localizedDescription]);
}
for (NSManagedObject *managedObject in items) {
[self.managedObjectContext deleteObject:managedObject];
}
if (![self.managedObjectContext save:&error]) {
NSLog(@"Error deleting %@ - error:%@", entityDescription, [error localizedDescription]);
}
}
}
如果您想删除所有对象但不想删除后备文件,可以使用以下方法:
- (void)deleteAllObjectsInContext:(NSManagedObjectContext *)context
usingModel:(NSManagedObjectModel *)model
{
NSArray *entities = model.entities;
for (NSEntityDescription *entityDescription in entities) {
[self deleteAllObjectsWithEntityName:entityDescription.name
inContext:context];
}
}
- (void)deleteAllObjectsWithEntityName:(NSString *)entityName
inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *fetchRequest =
[NSFetchRequest fetchRequestWithEntityName:entityName];
fetchRequest.includesPropertyValues = NO;
fetchRequest.includesSubentities = NO;
NSError *error;
NSArray *items = [context executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *managedObject in items) {
[context deleteObject:managedObject];
NSLog(@"Deleted %@", entityName);
}
}
请注意,它可能会非常缓慢(取决于您的对象图中有多少个对象)。
NSBatchDeleteRequest
。https://dev59.com/knNA5IYBdhLWcg3wIqPr#31961330 - Suragch