ios Основные данные: самый быстрый способ удалить все экземпляры объекта





11 Answers

Немного более очищен и универсален: добавьте этот метод:

- (void)deleteAllEntities:(NSString *)nameEntity
{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:nameEntity];
    [fetchRequest setIncludesPropertyValues:NO]; //only fetch the managedObjectID

    NSError *error;
    NSArray *fetchedObjects = [theContext executeFetchRequest:fetchRequest error:&error];
    for (NSManagedObject *object in fetchedObjects)
    {
        [theContext deleteObject:object];
    }

    error = nil;
    [theContext save:&error];
}
ios objective-c core-data

Я использую Core Data для локального сохранения результатов вызова Web Services. Веб-сервис возвращает полную объектную модель, скажем, «Автомобили» - может быть около 2000 из них (и я не могу заставить веб-службу вернуть что-либо меньшее, чем 1 или ВСЕ автомобили.

В следующий раз, когда я открою свое приложение, я хочу обновить сохраненную копию Core Data, снова вызвав веб-службу для всех автомобилей, однако для предотвращения дублирования мне необходимо сначала очистить все данные в локальном кеше.

Есть ли более быстрый способ очистить ВСЕ экземпляры определенного объекта в контексте управляемого объекта (например, все сущности типа «CAR»), или мне нужно запросить их вызов, затем выполнить итерацию результатов для их удаления, а затем сохранить?

В идеале я мог просто сказать, удалить все, где сущность Бла.




Для Swift 2.0:

class func clearCoreData(entity:String) {
  let fetchRequest = NSFetchRequest()
  fetchRequest.entity = NSEntityDescription.entityForName(entity, inManagedObjectContext: moc!)
  fetchRequest.includesPropertyValues = false
  do {
    if let results = try moc!.executeFetchRequest(fetchRequest) as? [NSManagedObject] {
      for result in results {
        moc!.deleteObject(result)
      }

      try moc!.save()
    }
  } catch {
    LOG.debug("failed to clear core data")
  }
}



Это аналогичный вопрос, который был here и кто-то предложил установить правило удаления отношений, поэтому вам нужно только удалить один объект. Поэтому, если у вас есть или может создать сущность с отношением «многие» к автомобилям и установить правило каскадирования при удалении высшей сущности, все машины также будут удалены. Это может сэкономить время обработки, так как вам не нужно выполнять шаги, связанные с загрузкой ВСЕХ автомобилей. В большем наборе данных это может быть абсолютно необходимо.




Расширение ответа Дейва Делонга.

Swift Version, которая также заботится о iOS 9 и предыдущих версиях. Я также рассмотрел обработку ошибок в этом:

let appDelegate: AppDelegate = UIApplication.sharedApplication (). делегировать как! AppDelegate

    let fetchRequest = NSFetchRequest(entityName: "Car")
    if #available(iOS 9.0, *) {
        let delete = NSBatchDeleteRequest(fetchRequest: fetchRequest)
        do {
            try appDelegate.persistentStoreCoordinator.executeRequest(delete, withContext: appDelegate.managedObjectContext)
        } catch let error as NSError {
            print("Error occured while deleting: \(error)")
        }
    } else {
        // Fallback on earlier versions
        let carRequest = NSFetchRequest()
        carRequest.entity = NSEntityDescription.entityForName("Cars", inManagedObjectContext: appDelegate.managedObjectContext)
        carRequest.includesPropertyValues = false

        do {
            let cars: NSArray = try appDelegate.managedObjectContext.executeFetchRequest(carRequest)

            for car in cars {
                appDelegate.managedObjectContext.delete(car)
            }

            try appDelegate.managedObjectContext.save()

        } catch let error as NSError {
            print("Error occured while fetching or saving: \(error)")
        }
    }



iOS 10 и более поздние версии

Работает со всеми версиями. Перенесите имя объекта и выполните итерацию, чтобы удалить все записи и сохранить контекст.

func deleteData(entityToFetch: String, completion: @escaping(_ returned: Bool) ->()) {
        let context = NSManagedObjectContext()
        context = your managedObjectContext

        let fetchRequest = NSFetchRequest<NSFetchRequestResult>()
        fetchRequest.entity = NSEntityDescription.entity(forEntityName: entityToFetch, in: context)
        fetchRequest.includesPropertyValues = false
         do {   
            let results = try context.fetch(fetchRequest) as! [NSManagedObject]
            for result in results {
                context.delete(result)
            }
            try context.save()
            completion(true)
        } catch {
            completion(false)
            print("fetch error -\(error.localizedDescription)")
        }
    }



Обновление Swift 4, iOS 12 и Xcode 10

100% работает только вырезать и вставлять

Просто поместите эту функцию в соответствующий класс
и вызовите эту функцию self.deleteData() в viewDidLoad()

или в любом месте или под функцией или кнопкой, так что, щелкнув по кнопке, все данные из объекта должны быть удалены и заменить «myEntity» в качестве объекта, который вы определили в своих основных данных

  func deleteData() {

  let appDel:AppDelegate = (UIApplication.shared.delegate as! AppDelegate)
  let context:NSManagedObjectContext = appDel.persistentContainer.viewContext
  let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "myEntity")
        fetchRequest.returnsObjectsAsFaults = false

        do
        {
            let results = try context.fetch(fetchRequest)
            for managedObject in results
            {
                let managedObjectData:NSManagedObject = managedObject as! NSManagedObject
                context.delete(managedObjectData)
            }
        } catch let error as NSError {
            print("Deleted all my data in myEntity error : \(error) \(error.userInfo)")
  }
  }



В Swift 3.0

 func deleteAllRecords() {
        //delete all data
        let context = appDelegate.persistentContainer.viewContext

        let deleteFetch = NSFetchRequest<NSFetchRequestResult>(entityName: "YourClassName")
        let deleteRequest = NSBatchDeleteRequest(fetchRequest: deleteFetch)

        do {
            try context.execute(deleteRequest)
            try context.save()
        } catch {
            print ("There was an error")
        }
    }



Ответ Dave Delongs Swift 2.0 для меня рушился (в iOS 9)

Но это сработало:

let fetchRequest = NSFetchRequest(entityName: "Car")
let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)

    do {
        try managedObjectContext.executeRequest(deleteRequest)
        try managedObjectContext.save()
    }
    catch let error as NSError {
       // Handle error
    }



Используйте NSBatchDeleteRequest для удаления нескольких записей. Если минимальная iOS равна 9.0. Если фоновый поток, выполните NSManagedObjectContext save else, используйте NSFetchRequest для получения записей и удаления всех записей в цикле и сохранения после удаления.




в iOS 11.3 и Swift 4.1

let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
        let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest )
        batchDeleteRequest.resultType = .resultTypeCount
        do {
            let batchDeleteResult = try dataController.viewContext.execute(batchDeleteRequest) as! NSBatchDeleteResult
            print("The batch delete request has deleted \(batchDeleteResult.result!) records.")
            dataController.viewContext.reset() // reset managed object context (need it for working)
        } catch {
            let updateError = error as NSError
            print("\(updateError), \(updateError.userInfo)")
        }

вы должны вызвать сброс после выполнения. Если нет, он не будет обновляться в представлении таблицы.




В Swift 2.0:

func deleteAllData(entity: String)
{
    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    let managedContext = appDelegate.managedObjectContext
    let fetchRequest = NSFetchRequest(entityName: entity)
    fetchRequest.returnsObjectsAsFaults = false

    do 
    {
        let results = try managedContext.executeFetchRequest(fetchRequest)
        for managedObject in results
        {
            let managedObjectData:NSManagedObject = managedObject as! NSManagedObject
            managedContext.deleteObject(managedObjectData)
        }
    } catch let error as NSError {
        print("Detele all data in \(entity) error : \(error) \(error.userInfo)")
    }
}



Related