कोर डेटा: एक इकाई के सभी उदाहरणों को हटाने का सबसे तेज़ तरीका


383

मैं वेब सेवा कॉल से स्थानीय रूप से परिणाम जारी रखने के लिए कोर डेटा का उपयोग कर रहा हूं। वेब सेवा के लिए पूर्ण ऑब्जेक्ट मॉडल लौटाता है, मान लें कि "कारें" - उनमें से लगभग 2000 हो सकती हैं (और मैं वेब सेवा को 1 या सभी कारों से कम कुछ भी नहीं दे सकता।

अगली बार जब मैं अपना आवेदन खोलूंगा, तो मैं सभी कारों के लिए वेब सेवा पर फिर से कॉल करके कोर डेटा को बनाए रखना चाहता हूं, हालांकि डुप्लिकेट को रोकने के लिए मुझे पहले स्थानीय कैश में सभी डेटा को शुद्ध करने की आवश्यकता होगी।

क्या प्रबंधित वस्तु संदर्भ में किसी विशिष्ट इकाई के सभी उदाहरणों को शुद्ध करने का एक तेज़ तरीका है (उदाहरण के लिए "CAR" के सभी निकाय), या क्या मुझे उन्हें कॉल करने की आवश्यकता है, फिर प्रत्येक को हटाने के लिए परिणामों के माध्यम से पुनरावृति करें, फिर सहेजें?

आदर्श रूप में मैं बस इतना कह सकता हूं कि जहां ब्लाह है वहां सभी को हटा दें।


आप मेमोरी डेटाबेस में एक का उपयोग कर सकते हैं
जे डोए

जवाबों:


718

iOS 9 और बाद में:

iOS 9 ने एक नया वर्ग जोड़ा NSBatchDeleteRequestहै जो आपको उन सभी को मेमोरी में लोड किए बिना एक विधेय से मिलान करने वाली वस्तुओं को आसानी से हटाने की अनुमति देता है। यहां बताया गया है कि आप इसका उपयोग कैसे करेंगे:

स्विफ्ट 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
}

उद्देश्य सी

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

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

WWDC 2015 से "व्हाट्स न्यू इन कोर डेटा" सत्र में बैच विलोपन के बारे में अधिक जानकारी प्राप्त की जा सकती है (~ 14: 10 से शुरू)।

iOS 8 और इससे पहले:

सभी को लाएं और उन्हें सभी हटाएं:

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
मैं पूरी तरह से ऑब्जेक्ट संरचना में लोड होने से किसी भी ओवरहेड को कम करने के लिए केवल NSManagedObjectID को पुनः प्राप्त करने के लिए भी कॉन्फ़िगर करेगा।
मार्कस एस। ज़रा

38
यह स्पष्ट नहीं है कि केवल NSMangagedObjectID को कैसे लाया जाए .. का उपयोग करें [allCars setIncludesPropertyValues: NO]; (और वस्तु आईडी के लिए एक NSPropertyDescription बनाने के लिए आसपास के शिकार को परेशान न करें!)
ओहोरोब

6
नौसिखिया प्रश्न के लिए खेद है: क्या आपको लूप की समाप्ति के बाद संदर्भ को बचाने की आवश्यकता है? जैसे [myContext save];
स्टीव

6
कोर डेटा में कोई नई सुविधा इसे और अधिक कुशल बनाने के लिए? यह मेरे ऐप के लिए एक गंभीर समस्या है जो पहले से ही कोर डेटा के लिए सड़क पोर्टिंग से नीचे है। इसकी कई सेकंड्स में से केवल 4000 प्रविष्टियों को हटाने में कई सेकंड लगते हैं। उपयोगकर्ता को प्रतीक्षा करने के लिए यह बहुत लंबा है। Sqlite के साथ सीधे एक ही अनुरोध तात्कालिक लगता है।
डेविड

4
@DaveDeLong NSBatchDeleteRequest NSFetchedResultsController प्रतिनिधि को कैसे ट्रिगर कर सकता है? मैं लगभग सब कुछ करने की कोशिश करता हूं, लेकिन कुछ भी नहीं होता है।
वन

36

स्विफ्ट 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")
        }
    }

32

थोड़ा और अधिक साफ और सार्वभौमिक: इस विधि को जोड़ें:

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

स्विफ्ट 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")
  }
}

12

स्विफ्ट:

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
इस उत्तर को नई कोशिश / कैच एरर हैंडलिंग से अपडेट किया जाना चाहिए
Suragch

10

यह यहां एक व्यक्ति के लिए एक समान प्रश्न है और किसी ने सुझाव दिया है कि एक संबंध हटाने का नियम स्थापित करें ताकि आपको केवल एक वस्तु को हटाना पड़े। इसलिए यदि आपके पास कारों के लिए कई संबंधों के साथ एक इकाई बना सकते हैं और जब आप उच्च इकाई को हटाते हैं तो कैस्केड करने के लिए डिलीट नियम को सेट करें। यह कुछ प्रसंस्करण समय बचा सकता है क्योंकि आपको सभी कारों को लोड करने से जुड़े कदम नहीं उठाने होंगे। एक बड़े डेटा सेट में यह बिल्कुल आवश्यक हो सकता है।


1
मैंने लगभग 600 कोर डेटा ऑब्जेक्ट्स के साथ अपने वर्तमान प्रोजेक्ट पर यह कोशिश की। जब मैंने उन्हें कैस्केड के साथ किसी अन्य ऑब्जेक्ट में समझाया, तो इसे हटाने के लिए लगभग 9.1 सेकंड का समय लगा। अगर मैंने डेव द्वारा सुझाई गई विधि का उपयोग किया तो इसे हटाने में लगभग 8.7 सेकंड लगते हैं। मेरे लिए उल्लेखनीय अंतर नहीं है।
एंड्रयू ज़िमर

8

एक अच्छा जवाब पहले से ही पोस्ट किया गया था, यह केवल एक सिफारिश है!

एक अच्छा तरीका सिर्फ एक श्रेणी जोड़ना NSManagedObjectऔर एक विधि को लागू करना होगा जैसे मैंने किया था:

हैडर फ़ाइल (जैसे NSManagedObject+Ext.h)

@interface NSManagedObject (Logic)

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

@end

कोड फ़ाइल: (जैसे 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

... केवल एक चीज जो आपको करनी है, वह है AppO डेलिगेट से ManageObjectContext प्राप्त करना, या जहां प्रत्येक के पास यह है;);

बाद में आप इसका उपयोग कर सकते हैं जैसे:

[NSManagedObject deleteAllFromEntity:@"EntityName"];

एक और अनुकूलन यह हो सकता है कि आप tha Unitname के पैरामीटर को हटा दें और clazzname के बजाय नाम प्राप्त करें। इससे उपयोग को बढ़ावा मिलेगा:

[ClazzName deleteAllFromEntity];

एक अधिक स्वच्छ प्रत्यारोपण (श्रेणी के रूप में 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

तब उपयोग:

[managedObjectContext deleteAllFromEntity:@"EntityName"];

1
क्षमा करें, लेकिन [AppDelegate managedObjectContext]जरूरी नहीं कि एक "स्वच्छ वास्तुकला" है; ;-)
डैनियल रिंसर

ठीक है, सच है। ऊपर इसका कोड एक प्रबंधितObjectContext पर आधारित है। प्राथमिक एक;) मल्टीथ्रेडेड कोड में, मैं सामान्य रूप से अन्य लोगों के लिए ऐप प्रतिनिधि के मुख्य एमओसी का विलय करता
हूं

1
@DanielRinser हो सकता हैdeleteAllFromEntity: inManagedObjectContext:
मोहम्मद एल्कासस

हाँ। बेहतर होगा कि एक क्लास विधि से ऑब्जेक्ट विधि में deleteAllFromEntity विधि को बदलें। तो आप एक MOC उदाहरण पर deleteAllFromEntity को सीधे कॉल कर सकते हैं।
एरहार्ड डिनहोब्ल

7

स्विफ्ट 4, आईओएस 12 और एक्सकोड 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 {
            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)")
    }
}

धन्यवाद, लेकिन NSBatchDeleteRequest अवधारणा ओएस काम क्यों नहीं कर रहा है? कोई उपाय।
सुरेश दुरिशेट्टी

@SureshDurishetti क्या आपने अपनी कक्षा में CoreData आयात किया है?
Xcodian सोलंगी

1
हाँ, CoreDate जोड़ा गया। लेकिन किस्मत नहीं।
सुरेश दुरिशेट्टी

4
आप संदर्भ में कॉल सेव जोड़ना भूल गए, संदर्भ जोड़ें। सेव () और आप जाने के लिए अच्छे हैं
परम धर्मिका

हां, इसे संदर्भ को बचाने की आवश्यकता है अन्यथा कोई परिवर्तन नहीं होगा
सुरेंद्र कुमार

5

स्विफ्ट 3. एक्स और स्विफ्ट 4. एक्स , आसान तरीका। केवल अपने आप को बदलें

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

इसके अलावा, आप इस निर्माण का उपयोग कर सकते हैं: गर्भपात करें: NSFetchRequest <NSFetchRequestResult> = YourTable.fetchRequest ()
Daniil Chuiko

5

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

2
अपना उत्तर पोस्ट करने के लिए धन्यवाद। ये मेरे लिए सही है। लेकिन आपको यहां अपना कोड कॉपी और पेस्ट नहीं करना चाहिए। एक newbee के लिए यह स्पष्ट नहीं है कि आपके CoreDataStack()या DataController()वर्ग क्या हैं। एक अद्यतन की सराहना की जाएगी;)
निको एस।

4

डेव डेलॉन्ग के जवाब का विस्तार।

स्विफ्ट संस्करण जो आईओएस 9 और पिछले संस्करणों का भी ख्याल रखता है। मैंने इसमें एरर हैंडलिंग को भी कवर किया है:

appDelegate दें: AppDelegate = UIApplication.saredApplication ()। प्रतिनिधि के रूप में! 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 9 तरीका वास्तव में महत्वपूर्ण है।
शोभाकर तिवारी

2

मौजूदा कैश के साथ आपको मिलने वाले डेटा में गुना क्यों नहीं? अन्यथा यह वास्तव में 'ताज़ा' नहीं है, यह 'फिर से शुरू हो रहा है' और आप SQLLite फ़ाइल को ड्रॉप / डिलीट कर सकते हैं और फिर से शुरू कर सकते हैं (यह मानते हुए कि आप अन्य डेटा भी जारी नहीं कर रहे हैं)।


1
बुरा हल। यदि Sqlite डेटाबेस में अन्य टेबल हैं, तो हम स्पष्ट रूप से वह सब ढीला कर देंगे। यह एक विशेष समाधान के लिए अधिक हैक है और बड़े मामलों के लिए विचार नहीं किया जा सकता है।
दीपक जीएम

2

स्विफ्ट 4, आईओएस 10+
स्टैटिक फ़ंक्शन जो किसी भी इकाई के लिए अपने सभी डेटा को हटाने के लिए आवेदन कर सकता है

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

'कक्ष' एक इकाई है

Room.removeAllObjectsInContext(self.persistentContainer.viewContext)

20191025 पर संपादित: "Self.fetchRequest ()" निर्देश समस्या का कारण हो सकता है यदि हम एक ही परियोजनाओं में कई लक्ष्य का उपयोग करते हैं। इसलिए NSFetchRequest (निकायनाम: स्ट्रिंग (वर्णन करना: स्वयं)) के साथ प्रतिस्थापित किया गया


1

यदि इकाई में बहुत सारी प्रविष्टियाँ हैं तो सबसे अच्छा तरीका इस तरह है क्योंकि यह मेमोरी को बचाता है

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

स्विफ्ट 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")
        }
    }

1

यह कोड iOS 9 और नीचे दोनों के लिए काम करेगा

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 और बाद में:

NSBatchDeleteRequestकोर डेटा में रिकॉर्ड को हटाने के लिए प्रयोग किया जाता है। यह बहुत तेज़ी से काम करता है और एक इकाई से सभी रिकॉर्ड को हटाने के लिए कम समय लेता है। इसके लिए NSFetchRequestतर्क की आवश्यकता है। यदि आप किसी इकाई से सभी रिकॉर्ड हटाना चाहते हैं, तो आप इसका उपयोग कर सकते हैं और यह मेरे लिए काम करता है।

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 में सभी वस्तुओं का त्वरित शुद्धिकरण :

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

डेव डेलोंग्स की स्विफ्ट 2.0 का उत्तर मेरे लिए दुर्घटनाग्रस्त था (आईओएस 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
    }

0

IOS 9 'NSBatchDeleteRequest' के साथ स्विफ्ट 3 समाधान और 'NSManagedObjectContext' पर विस्तार के रूप में लागू किए गए पहले के iOS संस्करणों में गिरावट। 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) }
            }
        }
    }
}

0

यदि न्यूनतम iOS 9.0 है, तो कई रिकॉर्ड को हटाने के लिए NSBatchDeleteRequest का उपयोग करें। यदि बैकग्राउंड थ्रेड, NSManagedObjectContext को कार्यान्वित करता है, तो रिकॉर्ड प्राप्त करने के लिए NSFetchRequest का उपयोग करें और लूप के लिए सभी रिकॉर्ड हटाएं और एक बार डिलीट होने से बचाएं।


0

iOS 11.3 और स्विफ्ट 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)")
        }

आपको निष्पादित करने के बाद रीसेट को कॉल करना होगा। यदि नहीं, तो यह तालिका दृश्य पर अपडेट नहीं होगा।


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

संस्थाओं के नाम के रूप में बिना किसी तार के OOP तरीका स्विफ्ट 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
    }
}

तो बस करो / पकड़ ब्लॉक में कॉल करें

    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

स्विफ्ट 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)")
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.