Temel Veriler: Bir varlığın tüm örneklerini silmenin en hızlı yolu


383

Bir Web Hizmetleri çağrısından gelen sonuçları yerel olarak devam ettirmek için Temel Verileri kullanıyorum. Web hizmeti, "Arabalar" için tam nesne modelini döndürür - bunlardan yaklaşık 2000 tane olabilir (ve Web Hizmetinin 1 veya TÜM arabalardan daha az bir şey döndürmesini sağlayamıyorum.

Uygulamamı bir sonraki açışımda, tüm Otomobiller için Web Hizmetini tekrar çağırarak Temel Veri kalıcı kopyasını yenilemek istiyorum, ancak yinelenmeleri önlemek için önce yerel önbellekteki tüm verileri temizlemem gerekiyor.

Yönetilen nesne bağlamında (örneğin "CAR" türündeki tüm varlıklar) belirli bir varlığın TÜM örneklerini temizlemenin daha hızlı bir yolu var mı, yoksa bunları çağırmak, sonra her birini silmek için sonuçları yinelemek, sonra kaydetmek mi?

İdeal olarak, varlığın Blah olduğu tüm yerleri sil diyebilirim.


Bellek içi veritabanı kullanabilirsiniz
J. Doe

Yanıtlar:


718

iOS 9 ve üstü:

iOS 9 NSBatchDeleteRequest, yüklemle eşleşen nesneleri hepsini belleğe yüklemenize gerek kalmadan kolayca silmenizi sağlayan yeni bir sınıf ekledi . İşte nasıl kullanacağınız:

Hızlı 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
}

Objective-C

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

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

Toplu silme işlemleri hakkında daha fazla bilgi WWDC 2015'teki "Çekirdek Verilerdeki Yenilikler" oturumunda bulunabilir (~ 14: 10'dan başlayarak).

iOS 8 ve öncesi:

Hepsini getir ve hepsini sil:

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

74
Ben de getirmeyi sadece NSManagedObjectID tam nesne yapısı yükleme herhangi bir yükü azaltmak için almak için yapılandırmak.
Marcus S. Zarra

38
Yalnızca NSMangagedObjectID nasıl getirileceği açık değildir. Use [allCars setIncludesPropertyValues: NO]; (ve nesne kimliği için bir NSPropertyDescription yapmak için etrafında avcılık zahmet etmeyin!)
ohhorob

6
acemi soru için özür dilerim: for döngüsü bittikten sonra içeriği kaydetmeniz mi gerekiyor? örneğin [myContext save];
Steve

6
Bunu daha verimli hale getirmek için Core Data'da yeni bir tesis var mı? Bu benim app için zaten çok temel verileri taşıyan yolda ciddi bir konudur. Birkaç tablonun sadece birinden 4000 girişi silmek birkaç saniye sürüyor. Bu, kullanıcının beklemesi için çok uzun. Doğrudan sqlite ile aynı istek anlık görünüyor.
David

4
@DaveDeLong NSBatchDeleteRequest, NSFetchedResultsController temsilcisini nasıl tetikleyebilir? Neredeyse her şeyi deniyorum, ama hiçbir şey olmuyor.
Foriger

36

Swift 3'te Varlığı Sıfırla :

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")
        }
    }

32

Biraz daha temiz ve evrensel: Bu yöntemi ekleyin:

- (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];
}

16

Swift 2.0 için:

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")
  }
}

12

Swift:

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)")
}

1
Bu cevap yeni deneme / yakalama hata işleme ile güncellenmelidir
Suragch

10

Bu bir benzer bir sorudur burada ve birisi yalnızca bir nesneyi silmek zorunda ilişki silme kuralı ayarlayarak önerdi. Dolayısıyla, araçlarla çok sayıda ilişkisi olan bir varlığınız varsa veya yapabilirseniz ve daha yüksek varlığı sildiğinizde silme kuralını kademeli olarak ayarladıysanız, tüm arabalar da silinecektir. TÜM arabaları yüklemekle ilgili adımları yapmak zorunda olmadığınız için bu işlemden biraz tasarruf edebilir. Daha büyük bir veri setinde bu kesinlikle gerekli olabilir.


1
Bunu şu anki projemde yaklaşık 600 temel veri nesnesi ile denedim. Onları basamaklı başka bir nesneye kapsüllediğimde silmek yaklaşık 9.1 saniye sürdü. Dave tarafından önerilen yöntemi kullandıysam, silmek yaklaşık 8.7 saniye sürer. Benim için dikkate değer bir fark yok.
Andrew Zimmer

8

İyi bir cevap zaten gönderildi, bu sadece bir tavsiye!

İyi bir yol sadece bir kategori eklemek NSManagedObjectve benim yaptığım gibi bir yöntem uygulamak olacaktır:

Başlık Dosyası (örn. NSManagedObject+Ext.h)

@interface NSManagedObject (Logic)

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

@end

Kod Dosyası: (örn. 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

... yapmanız gereken tek şey, uygulama temsilcisinden manageObjectContext'i veya içinde bulunduğunuz her yeri almaktır;)

daha sonra aşağıdaki gibi kullanabilirsiniz:

[NSManagedObject deleteAllFromEntity:@"EntityName"];

bir başka optimizasyon da bu varlık adı parametresini kaldırmanız ve clazzname yerine adı almanız olabilir. bu kullanıma yol açar:

[ClazzName deleteAllFromEntity];

daha temiz bir impl (NSManagedObjectContext kategorisi olarak):

@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

Kullanım sonra:

[managedObjectContext deleteAllFromEntity:@"EntityName"];

1
Üzgünüz, ama [AppDelegate managedObjectContext]mutlaka bir "temiz mimari" değil .. ;-)
Daniel Rinser

Tamam, doğru. Yukarıdaki kodu bir yönetilenObjectContext dayanmaktadır. birincil olanı;) Çok iş parçacıklı kodda normalde uygulama temsilcisinin ana
MOC'sini

1
@DanielRinser olabilirdeleteAllFromEntity: inManagedObjectContext:
Mohamed Elkassas

Evet. Daha iyi, deleteAllFromEntity yöntemini bir sınıf yönteminden bir nesne yöntemine değiştirmek olabilir. ardından deleteAllFromEntity öğesini doğrudan bir MOC örneğinde çağırabilirsiniz.
Erhard Dinhobl

7

Swift 4, iOS 12 ve Xcode 10 Güncellemesi

% 100 çalışma sadece kes ve yapıştır

Sadece bu işlevi ilgili sınıfa koyun ve bu işlevi bir işlev self.deleteData()içinde viewDidLoad()veya herhangi bir yerde ya da altında çağırın , böylece bir düğmeyi tıklatarak varlıktaki tüm veriler silinmeli ve "myEntity" ifadesini, temel veri

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)")
    }
}

Teşekkür ederim, ama neden NSBatchDeleteRequest concept os çalışmıyor? Herhangi bir fikir.
Suresh Durishetti

@SureshDurishetti, CoreData'yı sınıfınıza aktardınız mı?
Xcodian Solangi

1
Evet, CoreDate eklendi. Ama şans yok.
Suresh Durishetti

4
Bağlamda arama kaydetmeyi, bağlam.save () 'i eklemeyi unuttunuz ve gitmekte
fayda var

Evet, bu bağlamı kaydetmeyi gerektirir, aksi takdirde değişiklik olmaz
Surendra Kumar

5

Swift 3.X ve Swift 4.X , Kolay yol. Yalnızca YourTable'ınızı değiştirin

    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)")
    }

Ayrıca bu yapıyı kullanabilirsiniz: let fetchRequest: NSFetchRequest <NSFetchRequestResult> = YourTable.fetchRequest ()
Daniil Chuiko

5

iOS 10 ve üstü

Tüm sürümlerle çalışır. Varlık adını iletin ve tüm girişleri silmek ve içeriği kaydetmek için tekrarlayın.

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)")
        }
    }

2
Cevabınızı gönderdiğiniz için teşekkür ederiz. Bu benim için işe yarıyor. Ancak kodunuzu buraya kopyalayıp yapıştırmamalısınız. Yeni bir arı için sizin CoreDataStack()veya DataController()sınıflarınızın ne olduğu açık değildir . Bir güncelleme takdir edilecektir;)
Nico S.

4

Dave Delong'un cevabını genişletmek.

İOS 9 ve önceki sürümleri de ilgilendiren Swift Sürüm. Ayrıca bu Hata işleme kapsamış:

let appDelegate: AppDelegate = UIApplication.sharedApplication (). delege olarak! 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)")
        }
    }

oy verildi. ios 9 kayıt silme yolu gerçekten awsm olduğunu.
Shobhakar Tiwari

2

Neden mevcut önbellekle aldığınız verileri katlamıyorsunuz? Aksi takdirde gerçekten 'ferahlatıcı' değil, 'tekrar başlıyor' ve SQLLite dosyasını bırakıp silebilir ve yeniden başlayabilirsiniz (diğer verilere de devam etmediğini varsayarak).


1
Kötü çözüm. Sqlite veritabanında başka tablolar varsa, tüm bunları kaybedeceğiz. Bu, belirli bir çözüm için daha çok bir hack'tir ve daha büyük durumlar için düşünülemez.
Deepak GM

2


Herhangi bir varlığın tüm verilerini kaldırması için başvurabilen Swift 4, iOS 10+ Statik işlev

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)
        }
    }
}

'Oda' bir varlıktır

Room.removeAllObjectsInContext(self.persistentContainer.viewContext)

20191025'te düzenlendi: "Self.fetchRequest ()" talimatı, aynı projelerde birden fazla hedef kullanırsak soruna neden olabilir. Böylece NSFetchRequest ile değiştirildi (entityName: String (tanımlayan: self))


1

varlık çok fazla girdi içeriyorsa, bellek tasarrufu sağladığı için en iyi yol böyledir

 - (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];
    }
}

1

Swift 3.0'da

 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")
        }
    }

1

Bu kod hem iOS 9 hem de altı için çalışır

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()
    }

1

iOS 9.0 ve Üstü:

NSBatchDeleteRequestçekirdek verilerdeki kayıtları silmek için kullanılır. Çok hızlı çalışır ve bir varlıktaki tüm kayıtları silmek için daha az zaman alır. NSFetchRequestTartışmayı gerektirir . Bir varlıktaki tüm kayıtları silmek istiyorsanız, bunu kullanabilirsiniz ve benim için çalışır.

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)
    }

1

DB'deki tüm nesnelerin hızlı temizlenmesi :

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)")
      }
   }
 }

0

Dave Delongs'in Swift 2.0 cevabı benim için çöküyordu (iOS 9'da)

Ama bu işe yaradı:

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
    }

0

İOS 9 'NSBatchDeleteRequest' ile Swift 3 çözümü ve 'NSManagedObjectContext' üzerinde bir uzantı olarak uygulanan önceki iOS sürümlerine geri dönüş. Apple referansı 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) }
            }
        }
    }
}

0

Minimum iOS 9.0 ise birden çok kaydı silmek için NSBatchDeleteRequest kullanın. Arka plan iş parçacığı, yürütmek NSManagedObjectContext save else NSFetchRequest kullanarak kayıt almak ve döngü için tüm kayıtları silmek ve Silme işlemi tamamlandıktan sonra kaydet.


0

iOS 11.3 ve Swift 4.1'de

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)")
        }

yürüttükten sonra reset çağırmanız gerekir. Değilse, tablo görünümünde güncellenmez.


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)
    }
}

0

Swift 3+, Xcode 10+ olarak varlık dizeleri olmadan OOP yolu

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
    }
}

sonra sadece do / catch bloğunu arayın

    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
    }

-1

Swift 2.0'da:

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)")
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.