Data Inti: Cara tercepat untuk menghapus semua instance entitas

383

Saya menggunakan Data Inti untuk mempertahankan hasil dari panggilan Layanan Web secara lokal. Layanan web mengembalikan model objek penuh untuk, katakanlah, "Mobil" - bisa sekitar 2000 di antaranya (dan saya tidak bisa membuat Layanan Web mengembalikan apa pun yang kurang dari 1 atau SEMUA mobil.

Lain kali saya membuka aplikasi saya, saya ingin menyegarkan salinan Core Data yang bertahan dengan memanggil Layanan Web untuk semua Mobil lagi, namun untuk mencegah duplikat saya harus membersihkan semua data dalam cache lokal terlebih dahulu.

Apakah ada cara yang lebih cepat untuk membersihkan SEMUA instance entitas tertentu dalam konteks objek yang dikelola (misalnya semua entitas tipe "CAR"), atau apakah saya perlu meminta mereka memanggil, lalu beralih melalui hasil untuk menghapus masing-masing, lalu menyimpan?

Idealnya saya bisa mengatakan hapus semua di mana entitas Blah.

Adaroma
sumber
Anda dapat menggunakan basis data dalam memori
J. Doe

Jawaban:

718

iOS 9 dan yang lebih baru:

iOS 9 menambahkan kelas baru yang disebut NSBatchDeleteRequestyang memungkinkan Anda untuk dengan mudah menghapus objek yang cocok dengan predikat tanpa harus memuat semuanya ke dalam memori. Begini cara Anda menggunakannya:

Cepat 5

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

do {
    try myPersistentStoreCoordinator.execute(deleteRequest, with: myContext)
} catch let error as NSError {
    // TODO: handle the error
}

Objektif-C

NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Car"];
NSBatchDeleteRequest *delete = [[NSBatchDeleteRequest alloc] initWithFetchRequest:request];

NSError *deleteError = nil;
[myPersistentStoreCoordinator executeRequest:delete withContext:myContext error:&deleteError];

Informasi lebih lanjut tentang penghapusan kumpulan dapat ditemukan di sesi "Apa yang Baru di Data Inti" dari WWDC 2015 (mulai ~ 14: 10).

iOS 8 dan sebelumnya:

Ambil semuanya dan hapus semuanya:

NSFetchRequest *allCars = [[NSFetchRequest alloc] init];
[allCars setEntity:[NSEntityDescription entityForName:@"Car" inManagedObjectContext:myContext]];
[allCars setIncludesPropertyValues:NO]; //only fetch the managedObjectID

NSError *error = nil;
NSArray *cars = [myContext executeFetchRequest:allCars error:&error];
[allCars release];
//error handling goes here
for (NSManagedObject *car in cars) {
  [myContext deleteObject:car];
}
NSError *saveError = nil;
[myContext save:&saveError];
//more error handling here
Dave DeLong
sumber
74
Saya juga akan mengkonfigurasi pengambilan untuk hanya mengambil NSManagedObjectID untuk mengurangi overhead dari pemuatan dalam struktur objek penuh.
Marcus S. Zarra
38
Tidak jelas bagaimana cara hanya mengambil NSMangagedObjectID .. gunakan [allCars setIncludesPropertyValues: NO]; (Dan jangan repot-repot berburu di sekitar untuk bagaimana membuat NSPropertyDescription untuk ID objek!)
ohhorob
6
maaf untuk pertanyaan pemula: apakah Anda perlu menyimpan konteks setelah akhir dari for loop? misal [myContext save];
Steve
6
Adakah fasilitas baru di Core Data untuk menjadikan ini lebih efisien? Ini adalah masalah serius karena aplikasi saya sudah jauh-jauh melakukan porting ke Core Data. Butuh beberapa detik untuk menghapus semua 4000 entri dari hanya satu dari beberapa tabel. Ini terlalu lama bagi pengguna untuk menunggu. Permintaan yang sama secara langsung dengan sqlite tampaknya instan.
David
4
@DaveDeLong Bagaimana NSBatchDeleteRequest dapat memicu delegasi NSFetchedResultsController? Saya mencoba hampir semuanya, tetapi tidak ada yang terjadi.
Foriger
36

Setel Ulang Entitas di Swift 3 :

func resetAllRecords(in entity : String) // entity = Your_Entity_Name
    {

        let context = ( UIApplication.shared.delegate as! AppDelegate ).persistentContainer.viewContext
        let deleteFetch = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
        let deleteRequest = NSBatchDeleteRequest(fetchRequest: deleteFetch)
        do
        {
            try context.execute(deleteRequest)
            try context.save()
        }
        catch
        {
            print ("There was an error")
        }
    }
Roy
sumber
32

Sedikit lebih bersih dan universal: Tambahkan metode ini:

- (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];
}
Jon - LBAB
sumber
16

Untuk 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")
  }
}
Gaurav Sharma
sumber
12

Cepat:

let fetchRequest = NSFetchRequest()
fetchRequest.entity = NSEntityDescription.entityForName(entityName, inManagedObjectContext: context)
fetchRequest.includesPropertyValues = false

var error:NSError?
if let results = context.executeFetchRequest(fetchRequest, error: &error) as? [NSManagedObject] {
    for result in results {
        context.deleteObject(result)
    }

    var error:NSError?
    if context.save(&error) {
        // do something after save

    } else if let error = error {
        println(error.userInfo)
    }

} else if let error = error {
    println("error: \(error)")
}
Ixx
sumber
1
Jawaban ini harus diperbarui dengan penanganan kesalahan coba / tangkap yang baru
Suragch
10

Ini adalah pertanyaan yang mirip dengan yang ada di sini dan seseorang menyarankan untuk menyiapkan aturan penghapusan hubungan sehingga Anda hanya perlu menghapus satu objek. Jadi, jika Anda memiliki atau dapat membuat entitas dengan hubungan ke-banyak ke mobil dan mengatur aturan hapus ke kaskade ketika Anda menghapus entitas yang lebih tinggi semua mobil akan dihapus juga. Ini dapat menghemat waktu pemrosesan karena Anda tidak perlu melakukan langkah-langkah yang terkait dengan memuat SEMUA mobil. Dalam kumpulan data yang lebih besar ini bisa mutlak diperlukan.

T. Markle
sumber
1
Saya baru saja mencoba ini pada proyek saya saat ini dengan sekitar 600 objek data inti. Ketika saya merangkum mereka di objek lain dengan cascade butuh sekitar 9,1 detik untuk menghapus. Jika saya menggunakan metode yang disarankan oleh Dave tentang hal itu dibutuhkan sekitar 8,7 detik untuk menghapus. Bukan perbedaan penting bagi saya.
Andrew Zimmer
8

Jawaban yang bagus sudah diposting, ini hanya rekomendasi!

Cara yang baik adalah dengan hanya menambahkan kategori NSManagedObjectdan menerapkan metode seperti yang saya lakukan:

File Header (mis. NSManagedObject+Ext.h)

@interface NSManagedObject (Logic)

+ (void) deleteAllFromEntity:(NSString*) entityName;

@end

File Kode: (mis. NSManagedObject + Ext.m)

@implementation NSManagedObject (Logic)

+ (void) deleteAllFromEntity:(NSString *)entityName {
    NSManagedObjectContext *managedObjectContext = [AppDelegate managedObjectContext];
    NSFetchRequest * allRecords = [[NSFetchRequest alloc] init];
    [allRecords setEntity:[NSEntityDescription entityForName:entityName inManagedObjectContext:managedObjectContext]];
    [allRecords setIncludesPropertyValues:NO];
    NSError * error = nil;
    NSArray * result = [managedObjectContext executeFetchRequest:allRecords error:&error];
    for (NSManagedObject * profile in result) {
        [managedObjectContext deleteObject:profile];
    }
    NSError *saveError = nil;
    [managedObjectContext save:&saveError];
}

@end

... satu-satunya hal yang harus Anda lakukan adalah untuk mendapatkan managedObjectContext dari delegasi aplikasi, atau di mana setiap Anda memilikinya;)

setelah itu Anda bisa menggunakannya seperti:

[NSManagedObject deleteAllFromEntity:@"EntityName"];

satu optimasi lebih lanjut bisa jadi Anda menghapus parameter untuk thname entitas dan mendapatkan nama bukan dari clazzname. ini akan menyebabkan penggunaan:

[ClazzName deleteAllFromEntity];

imp yang lebih bersih (sebagai kategori untuk NSManagedObjectContext):

@implementation NSManagedObjectContext (Logic)

- (void) deleteAllFromEntity:(NSString *)entityName {
    NSFetchRequest * allRecords = [[NSFetchRequest alloc] init];
    [allRecords setEntity:[NSEntityDescription entityForName:entityName inManagedObjectContext:self]];
    [allRecords setIncludesPropertyValues:NO];
    NSError * error = nil;
    NSArray * result = [self executeFetchRequest:allRecords error:&error];
    for (NSManagedObject * profile in result) {
        [self deleteObject:profile];
    }
    NSError *saveError = nil;
    [self save:&saveError];
}

@end

Penggunaannya kemudian:

[managedObjectContext deleteAllFromEntity:@"EntityName"];
Erhard Dinhobl
sumber
1
Maaf, tetapi [AppDelegate managedObjectContext]tidak harus "arsitektur bersih" .. ;-)
Daniel Rinser
Ok benar Kode di atas didasarkan pada satu managedObjectContext. yang utama;) Dalam kode multithreaded saya biasanya menggabungkan MOC utama dari delegasi aplikasi ke yang lain
Erhard Dinhobl
1
@DanielRinser dapatdeleteAllFromEntity: inManagedObjectContext:
Mohamed Elkassas
Iya. Lebih baik mengubah metode deleteAllFromEntity dari metode kelas menjadi metode objek. maka Anda dapat memanggil deleteAllFromEntity langsung pada instance MOC.
Erhard Dinhobl
7

Pembaruan Swift 4, iOS 12 dan Xcode 10

100% berfungsi cukup potong & tempel

Cukup letakkan fungsi ini di kelas yang relevan dan panggil fungsi ini self.deleteData()di viewDidLoad()atau di mana saja atau di bawah fungsi atau tombol sehingga dengan mengklik tombol semua data dari entitas harus dihapus dan ganti "myEntity" sebagai entitas Anda yang telah Anda tentukan di data inti

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 {
            if 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)")
    }
}
Xcodian Solangi
sumber
Terima kasih, tetapi mengapa konsep NSBatchDeleteRequest os tidak berfungsi? ada ide.
Suresh Durishetti
@ SureshDurishetti sudahkah Anda mengimpor CoreData di kelas Anda?
Xcodian Solangi
1
Ya, tambah CoreDate. Tapi tidak berhasil.
Suresh Durishetti
4
Anda lupa menambahkan panggilan simpan pada konteksnya, tambahkan context.save () dan Anda dapat melakukannya
Parama Dharmika
Ya, ini perlu menyelamatkan konteks jika tidak, tidak akan ada perubahan
Surendra Kumar
5

Swift 3.X dan Swift 4.X , Cara mudah. Ubah hanya YourTable

    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "YourTable")
    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("Detele all my data in \(entity) error : \(error) \(error.userInfo)")
    }
Pengembang Swift
sumber
Anda juga dapat menggunakan konstruksi ini: let fetchRequest: NSFetchRequest <NSFetchRequestResult> = YourTable.fetchRequest ()
Daniil Chuiko
5

iOS 10 dan yang lebih baru

Bekerja dengan semua versi. Lulus nama entitas dan ulangi untuk menghapus semua entri dan menyimpan konteks.

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)")
        }
    }
Karun Kumar
sumber
2
Terima kasih telah mengirimkan jawaban Anda. Itu bekerja untuk saya. Tetapi Anda tidak boleh hanya menyalin & menempel kode Anda di sini. Untuk pemula, tidak jelas apa kelas Anda CoreDataStack()atau apa DataController(). Pembaruan akan dihargai;)
Nico S.
4

Memperluas jawaban Dave Delong.

Versi Swift yang menangani iOS 9 dan versi sebelumnya juga. Saya juga membahas penanganan Kesalahan dalam hal ini:

biarkan appDelegate: AppDelegate = UIApplication.sharedApplication (). delegasikan sebagai! 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)")
        }
    }
Maheen Khalid
sumber
terbalik. ios 9 cara menghapus catatan benar-benar awsm.
Shobhakar Tiwari
2

Mengapa tidak melipat data yang Anda terima dengan cache yang ada? Kalau tidak, itu tidak benar-benar 'menyegarkan', itu 'mulai lagi' dan Anda mungkin juga drop / menghapus file SQLLite dan mulai lagi (dengan asumsi Anda tidak bertahan data lain juga).

AlBlue
sumber
1
Solusi buruk Jika ada tabel lain dalam database Sqlite, kami jelas akan kehilangan semua itu. Ini lebih merupakan peretasan untuk solusi tertentu dan tidak dapat dipertimbangkan untuk kasus yang lebih besar.
Deepak GM
2

Swift 4, iOS 10+
Fungsi statis yang dapat diterapkan untuk entitas apa pun untuk menghapus semua datanya

protocol NSManagedObjectHelper {
}
extension NSManagedObject: NSManagedObjectHelper {
}
extension NSManagedObjectHelper where Self: NSManagedObject {
    static func removeAllObjectsInContext(_ managedContext: NSManagedObjectContext) {
        let request: NSFetchRequest = NSFetchRequest(entityName: String(describing: self))
        let deleteRequest = NSBatchDeleteRequest(fetchRequest: request)
        do {
            deleteRequest.resultType = .resultTypeObjectIDs//to clear objects from memory
            let result = try managedContext.execute(deleteRequest) as? NSBatchDeleteResult
            if let objectIDArray = result?.result as? [NSManagedObjectID] {
                let changes = [NSDeletedObjectsKey : objectIDArray]
                /*By calling mergeChangesFromRemoteContextSave, all of the NSManagedObjectContext instances that are referenced will be notified that the list of entities referenced with the NSManagedObjectID array have been deleted and that the objects in memory are stale. This causes the referenced NSManagedObjectContext instances to remove any objects in memory that are loaded which match the NSManagedObjectID instances in the array.*/
                NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [managedContext])
            }
            try managedContext.save()
        } catch let error {
            print(error)
        }
    }
}

'Kamar' adalah sebuah entitas

Room.removeAllObjectsInContext(self.persistentContainer.viewContext)

Diedit pada 20191025: instruksi "Self.fetchRequest ()" dapat menyebabkan masalah jika kita menggunakan beberapa target dalam proyek yang sama. Jadi diganti dengan NSFetchRequest (entityName: String (menggambarkan: self))

jpulikkottil
sumber
1

jika entitas berisi banyak entri, cara terbaik adalah seperti ini karena menghemat memori

 - (void)deleteAll:(NSManagedObjectContext *)managedObjectContext entityName:(NSString *)entityName
{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [managedObjectContext setUndoManager:nil];
    NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];
    [fetchRequest setIncludesPropertyValues:NO];
    [fetchRequest setFetchLimit:100]; // you can change this number if you want
    NSError *error;
    NSArray *items = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
    while ([items count] > 0) {
        @autoreleasepool {
            for (NSManagedObject *item in items) {
                [managedObjectContext deleteObject:item];
            }
            if (![managedObjectContext save:&error]) {
                NSLog(@"Error deleting %@ - error:%@",self.entityName, error);
            }
        }
        items = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
    }
}
demam poyo.
sumber
1

Di 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")
        }
    }
Amul4608
sumber
1

Kode ini akan berfungsi untuk iOS 9 dan di bawah

class func deleteAllRecords(in entity : String) // entity = Your_Entity_Name
    {

        let context = CoreDataStack.getContext() // Note:- Replace your context here with CoreDataStack.getContext()
        let deleteFetch = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
        if #available(iOS 9, *)
        {
            let deleteRequest = NSBatchDeleteRequest(fetchRequest: deleteFetch)
            do
            {
                try context.execute(deleteRequest)
                try context.save()
            }
            catch
            {
                print("There was an error:\(error)")
            }
        }
        else
        {
            do{
                let deleteRequest = try context.fetch(deleteFetch)
                for anItem in deleteRequest {
                    context.delete(anItem as! NSManagedObject)
                }
            }
            catch
            {
                print("There was an error:\(error)")
            }
        }
        CoreDataStack.saveContext() // Note:- Replace your savecontext here with CoreDataStack.saveContext()
    }
Varun Naharia
sumber
1

iOS 9.0 dan Selanjutnya:

NSBatchDeleteRequestdigunakan untuk menghapus catatan dalam data inti. Ini bekerja sangat cepat dan membutuhkan waktu lebih sedikit untuk menghapus semua catatan dari suatu entitas. Itu membutuhkan NSFetchRequestargumen. Jika Anda ingin menghapus semua catatan dari suatu entitas, Anda dapat menggunakannya dan berfungsi untuk saya.

let manageObject:NSManagedObjectContext = appDelegateObject.managedObjectContext

let fetchRequest = NSFetchRequest(entityName: EnityName”)

let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)

let persistCor:NSPersistentStoreCoordinator = appDelegateObject.persistentObject
 do {
        try persistCor.executeRequest(deleteRequest, withContext: manageObject)
        try manageObject.save()
    } catch {
        print(error?.localizedDescription)
    }
MARK Pengembang iOS
sumber
1

pembersihan cepat semua objek di DB:

func purgeAllData() {
    let uniqueNames = persistentContainer.managedObjectModel.entities.compactMap({ $0.name })

    uniqueNames.forEach { (name) in
      let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: name)
       let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
         do {
        try persistentContainer.viewContext.execute(batchDeleteRequest)
      } catch {
        let nserror = error as NSError
        fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
      }
   }
 }
gbk
sumber
0

Jawaban Swift 2.0 dari Dave Delongs tidak cocok untuk saya (di iOS 9)

Tetapi ini berhasil:

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
    }
cahaya
sumber
0

Solusi Swift 3 dengan iOS 9 'NSBatchDeleteRequest' dan fallback ke versi iOS sebelumnya diimplementasikan sebagai ekstensi pada 'NSManagedObjectContext'. Referensi Apple https://developer.apple.com/library/content/featuredarticles/CoreData_Batch_Guide/BatchDeletes/BatchDeletes.html

extension NSManagedObjectContext {
    func batchDeleteEntities<T: NSManagedObject>(ofType type: T.Type) throws {
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: String(describing: type.self))
        if #available(iOS 9.0, *) {
            let request = NSBatchDeleteRequest(fetchRequest: fetchRequest)
            let result = try execute(request) as? NSBatchDeleteResult
            if let objectIDArray = result?.result as? [NSManagedObjectID] {
                let changes = [NSDeletedObjectsKey: objectIDArray]
                NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [self])
            }
        } else {
            fetchRequest.includesPropertyValues = false
            let results = try fetch(fetchRequest)
            if let actualResults = results as? [NSManagedObject], !actualResults.isEmpty {
                actualResults.forEach { delete($0) }
            }
        }
    }
}
chriswillow
sumber
0

Gunakan NSBatchDeleteRequest untuk menghapus beberapa catatan Jika Minimum iOS adalah 9.0. Jika utas latar belakang, jalankan NSManagedObjectContext simpan yang lain gunakan NSFetchRequest untuk mendapatkan catatan dan menghapus semua catatan untuk loop dan Simpan setelah penghapusan dilakukan.

Jeetendra Kumar
sumber
0

di iOS 11.3 dan 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)")
        }

Anda harus memanggil ulang setelah Anda menjalankan. Jika tidak, itu tidak akan diperbarui pada tampilan tabel.

tien113
sumber
0
    func deleteAll(entityName: String) {

    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
    let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
    deleteRequest.resultType = .resultTypeObjectIDs
    guard let context = self.container?.viewContext
        else { print("error in deleteAll")
            return }

    do {
        let result = try context.execute(deleteRequest) as? NSBatchDeleteResult
        let objectIDArray = result?.result as? [NSManagedObjectID]
        let changes: [AnyHashable : Any] = [NSDeletedObjectsKey : objectIDArray as Any]
        NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [context])
    } catch {
        print(error.localizedDescription)
    }
}
Matt Bearson
sumber
0

cara OOP tanpa string sebagai nama entitas Swift 3+, Xcode 10+

func batchDelete<T>(in context: NSManagedObjectContext, fetchRequest: NSFetchRequest<T>) throws {
    guard let request = fetchRequest as? NSFetchRequest<NSFetchRequestResult> else {
        throw ErrorService.defaultError
    }
    let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: request)
    do {
        try context.execute(batchDeleteRequest)
    } catch {
        throw error
    }
}

maka cukup panggil do / catch block

    let fetchRequest: NSFetchRequest<YourEntity> = YourEntity.fetchRequest()
    do {
        let data = try context.fetch(fetchRequest)
        if data.count > 0 {
            try self.batchDelete(in: context, fetchRequest: fetchRequest)
        }
    } catch {
        // throw error
    }
Jack Daniel
sumber
-1

Dalam 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)")
    }
}
Rajesh Loganathan
sumber