【问题标题】:How do I delete all objects from my persistent store in Core Data?如何从 Core Data 的持久存储中删除所有对象?
【发布时间】:2011-01-23 11:17:17
【问题描述】:

我的应用中有 Core Data。因此,我获取一个 XML 文件,将数据解析为模型对象并将它们插入核心数据。它们保存在持久存储中,我可以在重新启动应用程序时访问它们。但是,我希望能够随意刷新持久存储中的数据,所以我需要先从存储中移除现有对象。有没有直接的方法?

谢谢


我找到了这个解决方案:

[managedObjectContext lock];
[managedObjectContext reset];//to drop pending changes
if ([persistentStoreCoordinator removePersistentStore:persistentStore error:&error])
{
NSURL* storeURL = [NSURL fileURLWithPath:[self pathForPersistentStore]];
[[NSFileManager defaultManager] removeFileAtPath:[storeURL path] handler:nil];
[self addPersistentStore];//recreates the persistent store
}
[managedObjectContext unlock];

【问题讨论】:

    标签: ios iphone cocoa-touch core-data


    【解决方案1】:

    您可以循环遍历所有对象并通过以下方式删除它们:

    [managedObjectContext deleteObject:someObject];
    

    如果要删除所有对象,最快的方法可能是删除存储,然后重新创建 CoreData 堆栈。

    【讨论】:

      【解决方案2】:

      放弃一切的最快方法是向托管对象上下文发送@987654321@ 消息。

      【讨论】:

      • 这不是清空上下文,而是将我的对象留在持久存储中吗?
      • 那是错误的。如果您的持久存储中有对象,这些对象将在下一个 fetchRequest 中重新获取。 reset 所做的只是使上下文当前持有的对 managedObjects 的所有引用无效。
      【解决方案3】:

      删除您的数据文件并重新制作。

      【讨论】:

      • 这些步骤有更详细的吗?
      • 当删除文件之前存在的私有上下文然后尝试保存时崩溃...
      【解决方案4】:

      这是我为彻底清理核心数据所做的工作。它完美地工作。这是如果您只有一个持久性存储,如果您没有手动添加一个,可能就是这种情况。如果您的 managedObjectContext 与此处的名称相同,您只需复制/粘贴即可。

      NSError * error;
      // retrieve the store URL
      NSURL * storeURL = [[managedObjectContext persistentStoreCoordinator] URLForPersistentStore:[[[managedObjectContext persistentStoreCoordinator] persistentStores] lastObject]];
      // lock the current context
      [managedObjectContext lock];
      [managedObjectContext reset];//to drop pending changes
      //delete the store from the current managedObjectContext
      if ([[managedObjectContext persistentStoreCoordinator] removePersistentStore:[[[managedObjectContext persistentStoreCoordinator] persistentStores] lastObject] error:&error])
      {
          // remove the file containing the data
          [[NSFileManager defaultManager] removeItemAtURL:storeURL error:&error];
          //recreate the store like in the  appDelegate method
          [[managedObjectContext persistentStoreCoordinator] addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error];//recreates the persistent store
      }
      [managedObjectContext unlock];
      //that's it !
      

      【讨论】:

      • 谢谢,非常好!一个问题:我们如何在 ARC 中使用“NSError ** error”?它给出了错误:'指向非常量类型“NSError **”的指针,没有明确的所有权'。
      • 是的,你必须用一些 preinfo 声明它,比如 _SomethingIDontRemeber NSError ** 错误,或者如果你不想要错误就传递 nil 会更容易...... ;)
      • 或者只是将第一行更改为'NSError *error',然后引用'&error'。
      • @NicolasManzini,你的代码对我不起作用。检查一下stackoverflow.com/questions/14646595/…
      • 请注意 lock 已被弃用。解决方案应该是使用 performBlockAndWait:
      【解决方案5】:

      @Nicolas Manzini 的快速版本回答:

      if let psc = self.managedObjectContext?.persistentStoreCoordinator{
      
              if let store = psc.persistentStores.last as? NSPersistentStore{
      
                  let storeUrl = psc.URLForPersistentStore(store)
      
                  self.managedObjectContext?.performBlockAndWait(){
      
                      self.managedObjectContext?.reset()
      
                      var error:NSError?
                      if psc.removePersistentStore(store, error: &error){
                          NSFileManager.defaultManager().removeItemAtURL(storeUrl, error: &error)
                          psc.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeUrl, options: nil, error: &error)
                      }
                  }
              }
          }
      

      【讨论】:

      • 我真的需要这个thanx
      【解决方案6】:

      基于@Nicolas Manzini 的回答,我编写了一个 Swift 2.1 版本,几乎没有改进。我已将扩展名添加到NSManagedObjectContext。完整代码如下:

      import Foundation
      import CoreData
      
      extension NSManagedObjectContext
      {
          func deleteAllData()
          {
              guard let persistentStore = persistentStoreCoordinator?.persistentStores.last else {
                  return
              }
      
              guard let url = persistentStoreCoordinator?.URLForPersistentStore(persistentStore) else {
                  return
              }
      
              performBlockAndWait { () -> Void in
                  self.reset()
                  do
                  {
                      try self.persistentStoreCoordinator?.removePersistentStore(persistentStore)
                      try NSFileManager.defaultManager().removeItemAtURL(url)
                      try self.persistentStoreCoordinator?.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil)
                  }
                  catch { /*dealing with errors up to the usage*/ }
              }
          }
      }
      

      【讨论】:

      • 完美,正是我需要的。谢谢!
      • 这是每个人都在寻找的答案,完美!
      【解决方案7】:

      有一个function

      根据WWDC 242,可以用来清库。

      还有一个func replacePersistentStore 正在用选定的数据库替换当前数据库。

      【讨论】:

        【解决方案8】:
        import Foundation
        import CoreData
        
        extension NSManagedObjectContext
        {
            func deleteAllData() {
                guard let persistentStore = persistentStoreCoordinator?.persistentStores.last else {
                    return
                }
        
                guard let url = persistentStoreCoordinator?.url(for: persistentStore) else   {
                    return
                }
        
                performAndWait { () -> Void in
                    self.reset()
                     do
                    {
                        try self.persistentStoreCoordinator?.remove(persistentStore)
                        try FileManager.default.removeItem(at: url)
                        try self.persistentStoreCoordinator?.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: nil)
                     }
                    catch { /*dealing with errors up to the usage*/ }
                 }
            }
        }
        

        感谢@Julian Krol - Swift 5.1 的更新答案

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-12-14
          • 1970-01-01
          • 2013-07-18
          • 1970-01-01
          • 1970-01-01
          • 2011-09-28
          • 1970-01-01
          相关资源
          最近更新 更多