您知道有什么方法可以删除存储在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);
}
}
其他回答
如果你想删除所有对象(这比拆除Core Data堆栈简单得多,但性能较差),那么这是一个更好的实现:
- (void)deleteAllManagedObjectsInModel:(NSManagedObjectModel *)managedObjectModel context:(NSManagedObjectContext *)managedObjectContext
{
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
[managedObjectContext performBlockAndWait:^{
for (NSEntityDescription *entity in managedObjectModel) {
NSFetchRequest *fetchRequest = [NSFetchRequest new];
[fetchRequest setEntity:entity];
[fetchRequest setIncludesSubentities:NO];
NSArray *objects = [managedObjectContext executeFetchRequest:fetchRequest error:nil];
for (NSManagedObject *managedObject in objects) {
[managedObjectContext deleteObject:managedObject];
}
}
[managedObjectContext save:nil];
}];
}];
[operation setCompletionBlock:^{
// Do stuff once the truncation is complete
}];
[operation start];
}
这个实现利用NSOperation来执行主线程的删除,并在完成时通知。您可能希望在完成块中发出通知或其他内容,以便将状态冒泡回主线程。
我从一个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;
您还可以查找所有实体名称,并按名称删除它们。它是一个较长的版本,但工作得很好,这样你就不必使用持久性存储
- (void)clearCoreData
{
NSError *error;
NSEntityDescription *des = [NSEntityDescription entityForName:@"Any_Entity_Name" inManagedObjectContext:_managedObjectContext];
NSManagedObjectModel *model = [des managedObjectModel];
NSArray *entityNames = [[model entities] valueForKey:@"name"];
for (NSString *entityName in entityNames){
NSFetchRequest *deleteAll = [NSFetchRequest fetchRequestWithEntityName:entityName];
NSArray *matches = [self.database.managedObjectContext executeFetchRequest:deleteAll error:&error];
}
if (matches.count > 0){
for (id obj in matches){
[_managedObjectContext deleteObject:obj];
}
[self.database.managedObjectContext save:&error];
}
}
对于“Any_Entity_Name”,只需要给出任何一个实体的名称,我们只需要找出实体的实体描述。ValueForKey@"name"将返回所有实体名称。最后,别忘了保存。
下面这个版本可以删除每个表中的每条记录。
斯威夫特4
static func resetDatabase() {
do {
try dataStore.persistentStoreCoordinator.managedObjectModel.entities.forEach { (entity) in
if let name = entity.name {
let fetch = NSFetchRequest<NSFetchRequestResult>(entityName: name)
let request = NSBatchDeleteRequest(fetchRequest: fetch)
try mainContext.execute(request)
}
}
try mainContext.save()
} catch {
print("error resenting the database: \(error.localizedDescription)")
}
}
从fileURLPath中删除sqlite,然后构建。