您知道有什么方法可以删除存储在Core Data中的所有条目吗?我的schema应该保持不变;我只想把它重置为空白。
Edit
我希望以编程方式做到这一点,这样用户就可以基本上按下重置按钮。
您知道有什么方法可以删除存储在Core Data中的所有条目吗?我的schema应该保持不变;我只想把它重置为空白。
Edit
我希望以编程方式做到这一点,这样用户就可以基本上按下重置按钮。
当前回答
我采取了Grouchal的代码,为了加快速度,我使用了并发模式的枚举(NSEnumerationConcurrent),它比for循环快了一点(在我的应用程序中,我为测试人员添加了这个功能,以便他们可以清除数据和做测试用例,而不是删除和安装应用程序)
- (void)resetObjects
{
[self deleteAllObjectsInEntity:@"Entity1"];
[self deleteAllObjectsInEntity:@"Entity2"];
[self deleteAllObjectsInEntity:@"Entity3"];
[self deleteAllObjectsInEntity:@"Entity4"];
}
-(void) deleteAllObjectsInEntity:(NSString*) entityName
{
MainDataContext *coreDataContext = [MainDataContext sharedInstance];
NSManagedObjectContext *currentContext = coreDataContext.managedObjectContext;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:currentContext];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *items = [currentContext executeFetchRequest:fetchRequest error:&error];
[items enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSManagedObject * obj, NSUInteger idx, BOOL *stop) {
[currentContext deleteObject:obj];
}];
if (![currentContext save:&error]) {
NSLog(@"Error deleting %@ - error:%@",entityName,error);
}
}
其他回答
我从一个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。我在主视图控制器中声明了一个属性。(不要担心我用来保存和加载的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;
这个问题有几个很好的答案。这里有一个简洁的例子。前两行删除sqlite数据库。然后for:循环删除managedObjectContext内存中的任何对象。
NSURL *storeURL = [[(FXYAppDelegate*)[[UIApplication sharedApplication] delegate] applicationDocumentsDirectory] URLByAppendingPathComponent:@"AppName.sqlite"];
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil];
for (NSManagedObject *ct in [self.managedObjectContext registeredObjects]) {
[self.managedObjectContext deleteObject:ct];
}
我采取了Grouchal的代码,为了加快速度,我使用了并发模式的枚举(NSEnumerationConcurrent),它比for循环快了一点(在我的应用程序中,我为测试人员添加了这个功能,以便他们可以清除数据和做测试用例,而不是删除和安装应用程序)
- (void)resetObjects
{
[self deleteAllObjectsInEntity:@"Entity1"];
[self deleteAllObjectsInEntity:@"Entity2"];
[self deleteAllObjectsInEntity:@"Entity3"];
[self deleteAllObjectsInEntity:@"Entity4"];
}
-(void) deleteAllObjectsInEntity:(NSString*) entityName
{
MainDataContext *coreDataContext = [MainDataContext sharedInstance];
NSManagedObjectContext *currentContext = coreDataContext.managedObjectContext;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:currentContext];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *items = [currentContext executeFetchRequest:fetchRequest error:&error];
[items enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSManagedObject * obj, NSUInteger idx, BOOL *stop) {
[currentContext deleteObject:obj];
}];
if (![currentContext save:&error]) {
NSLog(@"Error deleting %@ - error:%@",entityName,error);
}
}
似乎有两种方法:
假设您的核心数据堆栈有一个典型的单例。
import CoreData
public let core = Core.shared
public final class Core {
static let shared = Core()
var container: NSPersistentContainer!
private init() {
container = NSPersistentContainer(name: "stuff")
//deleteSql()
container.loadPersistentStores { storeDescription, error in
if let error = error { print("Error loading... \(error)") }
}
//deleteAll()
}
func saveContext() { // typical save helper
if container.viewContext.hasChanges {
do { try container.viewContext.save()
} catch { print("Error saving... \(error)") }
}
}
然后……
func deleteSql() {
let url = FileManager.default.urls(
for: .applicationSupportDirectory,
in: .userDomainMask)[0].appendingPathComponent( "stuff.sqlite" )
guard FileManager.default.fileExists(atPath: url.path) else {
print("nothing to delete!")
return
}
do {
try container.persistentStoreCoordinator.destroyPersistentStore(
at: url, ofType: "sqlite", options: nil)
print("totally scorched the sql file. you DO now have to LOAD again")
}
catch {
print("there was no sql file there!")
}
}
func deleteAll() { // courtesy @Politta
for e in container.persistentStoreCoordinator.managedObjectModel.entities {
let r = NSBatchDeleteRequest(
fetchRequest: NSFetchRequest(entityName: e.name ?? ""))
let _ = try? container.viewContext.execute(r)
}
saveContext()
print("conventionally deleted everything from within core data. carry on")
}
}
.
1. 焦化SQL文件
感谢优秀的@J。能源部的答案。您完全销毁了sql文件。
你必须这样做
在加载核心数据之前,即在创建容器之后,但是 在真正载入商店之前。)
(注意示例代码“//deleteSql()”就在初始化之前。)
2. 逐个删除核心数据中的所有内容
感谢精彩的@Politta回答。一旦core data启动并运行,就可以随时执行此操作。
(注意示例代码“//deleteAll()”是在初始化之后。)
方法一在开发过程中可能更有用。方法二在生产中可能更有用(在相对不常见的情况下,由于某种原因需要擦除所有内容)。
iOS 10+的更新解决方案
使用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,请看这个问题。
来源:
核心数据:删除实体的所有实例的最快方法(包括Objective-C代码) Core Data的新内容(WWDC 2015视频) Core Data的新内容(WWDC 2016视频) 如何在iOS 10中使用核心数据 Core Data Swift 3.0有什么新功能