هل تريد حذف/إعادة تعيين كافة الإدخالات في البيانات الأساسية؟

StackOverflow https://stackoverflow.com/questions/1077810

سؤال

هل تعرف أي طريقة لحذف كافة الإدخالات المخزنة في البيانات الأساسية؟يجب أن يظل مخططي كما هو؛أريد فقط إعادة تعيينه إلى فارغ.


يحرر

إنني أتطلع إلى القيام بذلك برمجيًا حتى يتمكن المستخدم بشكل أساسي من النقر على ملف reset زر.

هل كانت مفيدة؟

المحلول

لا يزال بإمكانك حذف الملف برمجيًا، باستخدام NSFileManager:removeItemAtPath::طريقة.

NSPersistentStore *store = ...;
NSError *error;
NSURL *storeURL = store.URL;
NSPersistentStoreCoordinator *storeCoordinator = ...;
[storeCoordinator removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtPath:storeURL.path error:&error];

بعد ذلك، ما عليك سوى إضافة المتجر الدائم مرة أخرى للتأكد من إعادة إنشائه بشكل صحيح.

الطريقة البرمجية للتكرار عبر كل كيان تكون أبطأ وعرضة للخطأ.استخدام القيام بذلك بهذه الطريقة هو إذا كنت تريد حذف بعض الكيانات وليس غيرها.ومع ذلك، لا تزال بحاجة إلى التأكد من احتفاظك بالتكامل المرجعي وإلا فلن تتمكن من الاستمرار في تغييراتك.

إن مجرد إزالة المتجر وإعادة إنشائه يعد أمرًا سريعًا وآمنًا، ويمكن بالتأكيد إجراؤه برمجيًا في وقت التشغيل.

التحديث لنظام iOS5+

مع تقديم وحدة تخزين ثنائية خارجية (تسمح بـExternalBinaryDataStorage أو التخزين في ملف سجل خارجي) في iOS 5 وOS X 10.7، فإن حذف الملفات المشار إليها بواسطة عناوين URL الخاصة بالمتجر ليس كافيًا.ستترك ملفات التسجيل الخارجية خلفك.نظرًا لأن نظام تسمية ملفات السجلات الخارجية هذه ليس عامًا، فليس لدي حل عالمي حتى الآن.– 08 مايو 2012 الساعة 23:00

نصائح أخرى

يمكنك حذف ملف SQLite - لكنني اخترت القيام بذلك عن طريق مسح الجداول بشكل فردي باستخدام الوظائف:

- (void) deleteAllObjects: (NSString *) entityDescription  {
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:entityDescription inManagedObjectContext:_managedObjectContext];
    [fetchRequest setEntity:entity];

    NSError *error;
    NSArray *items = [_managedObjectContext executeFetchRequest:fetchRequest error:&error];
    [fetchRequest release];


    for (NSManagedObject *managedObject in items) {
        [_managedObjectContext deleteObject:managedObject];
        DLog(@"%@ object deleted",entityDescription);
    }
    if (![_managedObjectContext save:&error]) {
        DLog(@"Error deleting %@ - error:%@",entityDescription,error);
    }

}

السبب الذي جعلني أختار القيام بذلك جدولاً تلو الآخر هو أنه يجعلني أؤكد أثناء قيامي بالبرمجة أن حذف محتويات الجدول أمر معقول وأنه لا توجد بيانات أفضل الاحتفاظ بها.

سيكون القيام بذلك أبطأ بكثير من مجرد حذف الملف وسأقوم بالتغيير إلى حذف الملف إذا استغرقت هذه الطريقة وقتًا طويلاً.

حل محدث لنظام iOS 10+

يستخدم NSBatchDeleteRequest لحذف كافة الكائنات الموجودة في الكيان دون الحاجة إلى تحميلها في الذاكرة أو التكرار من خلالها.

// create the delete request for the specified entity
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = MyEntity.fetchRequest()
let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)

// get reference to the persistent container
let persistentContainer = (UIApplication.shared.delegate as! AppDelegate).persistentContainer

// perform the delete
do {
    try persistentContainer.viewContext.execute(deleteRequest)
} catch let error as NSError {
    print(error)
}

تم تحديث هذا الرمز لنظامي التشغيل iOS 10 وSwift 3.إذا كنت بحاجة إلى دعم iOS 9، راجع هذا السؤال.

مصادر:

لقد كتبت أ clearStores الطريقة التي تمر عبر كل متجر وحذفها من المنسق ونظام الملفات (ترك معالجة الأخطاء جانبًا):

NSArray *stores = [persistentStoreCoordinator persistentStores];

for(NSPersistentStore *store in stores) {
    [persistentStoreCoordinator removePersistentStore:store error:nil];
    [[NSFileManager defaultManager] removeItemAtPath:store.URL.path error:nil];
}

[persistentStoreCoordinator release], persistentStoreCoordinator = nil;

هذه الطريقة موجودة داخل أ coreDataHelper فئة تعتني (من بين أمور أخرى) بإنشاء متجر دائم عندما يكون صفراً.

أقوم بإزالة كافة البيانات من البيانات الأساسية على زر حدث في فئة HomeViewController:لقد ساعدني هذا المقال كثيرًا لدرجة أنني اعتقدت أنني سأساهم فيه.

-(IBAction)buttonReset:(id)sender
{
    NSLog(@"buttonReset Pressed");

    //Erase the persistent store from coordinator and also file manager.
    NSPersistentStore *store = [self.persistentStoreCoordinator.persistentStores lastObject];
    NSError *error = nil;
    NSURL *storeURL = store.URL;
    [self.persistentStoreCoordinator removePersistentStore:store error:&error];
    [[NSFileManager defaultManager] removeItemAtURL:storeURL error:&error];


    NSLog(@"Data Reset");

    //Make new persistent store for future saves   (Taken From Above Answer)
    if (![self.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
        // do something with the error
    }

}

لاحظ أنه من أجل الاتصال بـ self.persistentStoreCoordinator، قمت بالإعلان عن خاصية في Home View Controller.(لا تقلق بشأن ManageObjectContext الذي أستخدمه للحفظ والتحميل.)

@property (nonatomic, retain) NSManagedObjectContext        *   managedObjectContext;
@property (nonatomic, retain) NSPersistentStoreCoordinator  *   persistentStoreCoordinator;

ثم في AppDelegate ApplicationDidFinishLaunching مباشرة أدناه لإنشاء HomeViewController، لدي:

homeViewController = [[HomeViewController alloc] initWithNibName:@"HomeViewController" bundle:nil];
homeViewController.managedObjectContext = self.managedObjectContext;
homeViewController.persistentStoreCoordinator = self.persistentStoreCoordinator;

سجل سحري يجعل هذا سهلاً للغاية.

[MyCoreDataObject MR_truncateAll];

iOS9+، سويفت 2

حذف كافة الكائنات في كافة الكيانات

func clearCoreDataStore() {
    let entities = managedObjectModel.entities
    for entity in entities {
        let fetchRequest = NSFetchRequest(entityName: entity.name!)
        let deleteReqest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
        do {
            try context.executeRequest(deleteReqest)
        } catch {
            print(error)
        }
    }
}

[إجابة متأخرة ردًا على مكافأة تطلب ردودًا أحدث]

وبالنظر إلى الإجابات السابقة،

  • لا يزال جلب جميع العناصر وحذفها، كما اقترح @Grouchal وآخرون، حلاً فعالاً ومفيدًا.إذا كان لديك مخازن بيانات كبيرة جدًا، فقد يكون الأمر بطيئًا، لكنه لا يزال يعمل بشكل جيد جدًا.
  • إن مجرد إزالة مخزن البيانات، كما لاحظت أنت و@groundhog، لم يعد فعالاً.انها عفا عليها الزمن حتى لو كنت لا تستخدم وحدة تخزين ثنائية خارجية لأن iOS 7 يستخدم وضع WAL لتدوين يوميات SQLite.مع وضع WAL، قد تكون هناك ملفات دفتر يومية (يحتمل أن تكون كبيرة) موجودة لأي مخزن ثابت للبيانات الأساسية.

ولكن هناك طريقة مختلفة ومشابهة لإزالة المتجر الدائم الذي يعمل بالفعل.المفتاح هو وضع ملف المتجر الدائم الخاص بك في الدليل الفرعي الخاص به والذي لا يحتوي على أي شيء آخر.لا تقم فقط بوضعه في دليل المستندات (أو في أي مكان)، بل قم بإنشاء دليل فرعي جديد للمخزن الدائم فقط.ستكون محتويات هذا الدليل في نهاية المطاف هي ملف المتجر الدائم وملفات دفتر اليومية والملفات الثنائية الخارجية.إذا كنت تريد تدمير مخزن البيانات بالكامل، فاحذف هذا الدليل وسوف تختفي جميعها.

ستفعل شيئًا كهذا عند إعداد متجرك الدائم:

NSURL *storeDirectoryURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"persistent-store"];
if ([[NSFileManager defaultManager] createDirectoryAtURL:storeDirectoryURL
        withIntermediateDirectories:NO
        attributes:nil
        error:nil]) {
    NSURL *storeURL = [storeDirectoryURL URLByAppendingPathComponent:@"MyApp.sqlite"];
    // continue with storeURL as usual...
}

ثم عندما أردت إزالة المتجر،

[[NSFileManager defaultManager] removeItemAtURL:storeDirectoryURL error:nil];

يؤدي ذلك إلى إزالة الدليل الفرعي المخصص وجميع ملفات البيانات الأساسية الموجودة فيه بشكل متكرر.

يعمل هذا فقط إذا لم يكن لديك مخزنك الدائم بالفعل في نفس المجلد مثل البيانات المهمة الأخرى.مثل دليل المستندات، والذي ربما يحتوي على أشياء أخرى مفيدة فيه.إذا كان هذا هو الوضع لديك، فيمكنك الحصول على نفس التأثير من خلال البحث عن الملفات التي تبحث عنها يفعل تريد الاحتفاظ وإزالة كل شيء آخر.شيء مثل:

NSString *docsDirectoryPath = [[self applicationDocumentsDirectory] path];
NSArray *docsDirectoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:docsDirectoryPath error:nil];
for (NSString *docsDirectoryItem in docsDirectoryContents) {
    // Look at docsDirectoryItem. If it's something you want to keep, do nothing.
    // If it's something you don't recognize, remove it.
}

قد يكون هذا النهج عرضة للخطأ.عليك أن تكون متأكدًا تمامًا من أنك تعرف كل الملف الذي تريد الاحتفاظ به، وإلا قد تقوم بإزالة البيانات المهمة.من ناحية أخرى، يمكنك إزالة الملفات الثنائية الخارجية دون معرفة اسم الملف/الدليل المستخدم لتخزينها فعليًا.

إذا كنت تريد حذف جميع الكائنات ولا تريد حذف ملفات النسخ الاحتياطي، فيمكنك استخدام الطرق التالية:

- (void)deleteAllObjectsInContext:(NSManagedObjectContext *)context
                       usingModel:(NSManagedObjectModel *)model
{
    NSArray *entities = model.entities;
    for (NSEntityDescription *entityDescription in entities) {
        [self deleteAllObjectsWithEntityName:entityDescription.name
                                   inContext:context];
    }
}

- (void)deleteAllObjectsWithEntityName:(NSString *)entityName
                             inContext:(NSManagedObjectContext *)context
{
    NSFetchRequest *fetchRequest =
        [NSFetchRequest fetchRequestWithEntityName:entityName];
    fetchRequest.includesPropertyValues = NO;
    fetchRequest.includesSubentities = NO;

    NSError *error;
    NSArray *items = [context executeFetchRequest:fetchRequest error:&error];

    for (NSManagedObject *managedObject in items) {
        [context deleteObject:managedObject];
        NSLog(@"Deleted %@", entityName);
    }
}

احذر من أنه قد يكون بطيئًا جدًا (يعتمد على عدد الكائنات الموجودة في الرسم البياني للكائنات).

هنا هو الحل المشترك لتطهير البيانات الأساسية.

- (void)deleteAllObjectsInCoreData
{
    NSArray *allEntities = self.managedObjectModel.entities;
    for (NSEntityDescription *entityDescription in allEntities)
    {
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        [fetchRequest setEntity:entityDescription];

        fetchRequest.includesPropertyValues = NO;
        fetchRequest.includesSubentities = NO;

        NSError *error;
        NSArray *items = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];

        if (error) {
                NSLog(@"Error requesting items from Core Data: %@", [error localizedDescription]);
            }

        for (NSManagedObject *managedObject in items) {
            [self.managedObjectContext deleteObject:managedObject];
        }

        if (![self.managedObjectContext save:&error]) {
            NSLog(@"Error deleting %@ - error:%@", entityDescription, [error localizedDescription]);
        }
    }  
}

إذا كنت تريد اتباع مسار حذف جميع الكائنات (وهو أبسط بكثير من هدم مكدس البيانات الأساسية، ولكنه أقل أداءً)، فهذا تنفيذ أفضل:

- (void)deleteAllManagedObjectsInModel:(NSManagedObjectModel *)managedObjectModel context:(NSManagedObjectContext *)managedObjectContext
{
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        [managedObjectContext performBlockAndWait:^{
            for (NSEntityDescription *entity in managedObjectModel) {
                NSFetchRequest *fetchRequest = [NSFetchRequest new];
                [fetchRequest setEntity:entity];
                [fetchRequest setIncludesSubentities:NO];
                NSArray *objects = [managedObjectContext executeFetchRequest:fetchRequest error:nil];
                for (NSManagedObject *managedObject in objects) {
                    [managedObjectContext deleteObject:managedObject];
                }            
            }

            [managedObjectContext save:nil];
        }];
    }];
    [operation setCompletionBlock:^{
        // Do stuff once the truncation is complete
    }];
    [operation start];
}

ويستفيد هذا التنفيذ NSOperation لإجراء الحذف من الموضوع الرئيسي والإخطار عند الانتهاء.قد ترغب في إرسال إشعار أو شيء ما داخل كتلة الإكمال لإعادة الحالة إلى سلسلة المحادثات الرئيسية.

نظام iOS 10 + حل سويفت 3:

func clearCoreDataStore() {
    let delegate = UIApplication.shared.delegate as! AppDelegate
    let context = delegate.persistentContainer.viewContext

    for i in 0...delegate.persistentContainer.managedObjectModel.entities.count-1 {
        let entity = delegate.persistentContainer.managedObjectModel.entities[i]

        do {
            let query = NSFetchRequest<NSFetchRequestResult>(entityName: entity.name!)
            let deleterequest = NSBatchDeleteRequest(fetchRequest: query)
            try context.execute(deleterequest)
            try context.save()

        } catch let error as NSError {
            print("Error: \(error.localizedDescription)")
            abort()
        }
    }
}

يتكرر من خلال جميع كيانات البيانات الأساسية ويمسحها

فيما يلي إصدار مبسط إلى حد ما مع مكالمات أقل إلى AppDelegate self والجزء الأخير من التعليمات البرمجية الذي تم استبعاده من الإجابة ذات التصنيف الأعلى.لقد تلقيت أيضًا خطأ "لا يمكن الوصول إلى المتجر الدائم للكائن من منسق NSManagedObjectContext" لذلك كنت بحاجة فقط إلى إضافة ذلك مرة أخرى.

NSPersistentStoreCoordinator *storeCoordinator = [self persistentStoreCoordinator];
NSPersistentStore *store = [[storeCoordinator persistentStores] lastObject];
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"dataModel"];
NSError *error;

[storeCoordinator removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtPath:storeURL.path error:&error];

[_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error];

if (storeCoordinator != nil) {
    _managedObjectContext = [[NSManagedObjectContext alloc] init];
    [_managedObjectContext setPersistentStoreCoordinator:storeCoordinator];
}

الحل السريع:

class func deleteAllManagedObjects() {

        let modelURL = NSBundle.mainBundle().URLForResource("some string", withExtension: "mom")
        let mom = NSManagedObjectModel(contentsOfURL: modelURL)

        for entityName in mom.entitiesByName.keys {
            let fr = NSFetchRequest(entityName: entityName as String)
            let a = Utility.managedObjectContext().executeFetchRequest(fr, error: nil) as [NSManagedObject]
            for mo in a {
                Utility.managedObjectContext().deleteObject(mo)
            }
        }

        Utility.managedObjectContext().save(nil)
    }

كمرجع سريع لحفظ البحث في مكان آخر - يمكن إعادة إنشاء المتجر الدائم بعد حذفه باستخدام:

if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
// do something with the error
}

شكرا لهذا المنصب.لقد تابعته ونجح معي.ولكن كان لدي مشكلة أخرى لم يتم ذكرها في أي من الردود.لذلك لست متأكدًا مما إذا كان أنا فقط.

على أي حال، اعتقدت أنني سأنشر هنا المشكلة وطريقتي في حلها.

كان لدي بعض السجلات في قاعدة البيانات، وأردت تنظيف كل شيء قبل كتابة بيانات جديدة إلى قاعدة البيانات، لذلك فعلت كل شيء بما في ذلك

[[NSFileManager defaultManager] removeItemAtURL:storeURL error:&error]; 

ومن ثم استخدامها managedObjectContext للوصول إلى قاعدة البيانات (من المفترض أن تكون فارغة الآن)، بطريقة ما كانت البيانات لا تزال موجودة.بعد فترة من استكشاف الأخطاء وإصلاحها، وجدت أنني بحاجة إلى إعادة تعيين managedObjectContext, managedObject, managedObjectModel وpersistentStoreCoordinator, ، قبل أن أستخدمه managedObjectContext للوصول إلى قاعدة البيانات.الآن لدي قاعدة بيانات نظيفة للكتابة إليها.

عدة إجابات جيدة على هذا السؤال.وهنا واحدة موجزة لطيفة.أول سطرين يحذفان قاعدة بيانات sqlite.ثم ل:تقوم الحلقة بحذف أي كائنات في ذاكرة ManageDObjectContext.

NSURL *storeURL = [[(FXYAppDelegate*)[[UIApplication sharedApplication] delegate] applicationDocumentsDirectory] URLByAppendingPathComponent:@"AppName.sqlite"];
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil];
for (NSManagedObject *ct in [self.managedObjectContext registeredObjects]) {
    [self.managedObjectContext deleteObject:ct];
}

يمكنك أيضًا العثور على جميع أسماء الكيانات وحذفها بالاسم.إنها نسخة أطول ولكنها تعمل بشكل جيد، وبهذه الطريقة لن تضطر إلى العمل مع متجر الثبات

 - (void)clearCoreData
{
NSError *error;
NSEntityDescription *des = [NSEntityDescription entityForName:@"Any_Entity_Name" inManagedObjectContext:_managedObjectContext];
NSManagedObjectModel *model = [des managedObjectModel];
NSArray *entityNames = [[model entities] valueForKey:@"name"];

for (NSString *entityName in entityNames){

    NSFetchRequest *deleteAll = [NSFetchRequest fetchRequestWithEntityName:entityName];
    NSArray *matches = [self.database.managedObjectContext executeFetchRequest:deleteAll error:&error];

}
    if (matches.count > 0){
        for (id obj in matches){

            [_managedObjectContext deleteObject:obj];
        }
       [self.database.managedObjectContext save:&error];
    }
}

بالنسبة إلى "Any_Entity_Name"، ما عليك سوى إعطاء أي اسم من أسماء الكيانات الخاصة بك، ونحتاج فقط إلى معرفة وصف الكيان الذي توجد به كياناتك.سوف تقوم ValueForKey@"name" بإرجاع جميع أسماء الكيانات.وأخيرا، لا تنسى الحفظ.

الإجابة المقبولة صحيحة مع إزالة عنوان URL بواسطة NSFileManager، ولكن كما هو مذكور في تعديل iOS 5+، لا يتم تمثيل المتجر الدائم بملف واحد فقط.بالنسبة لمتجر SQLite، فهو *.sqlite و *.sqlite-shm و *.sqlite-wal ...لحسن الحظ منذ iOS 7+ يمكننا استخدام الطريقة

nsperSentiveStoreCoordinator +removeUbiquitousContAntAndPersisterStoreAturl: الخيارات: خطأ:

للعناية بالإزالة، لذا يجب أن يكون الكود كالتالي:

NSPersistentStore *store = ...;
NSError *error;
NSURL *storeURL = store.URL;
NSString *storeName = ...;
NSPersistentStoreCoordinator *storeCoordinator = ...;
[storeCoordinator removePersistentStore:store error:&error];
[NSPersistentStoreCoordinator removeUbiquitousContentAndPersistentStoreAtURL:storeURL.path options:@{NSPersistentStoreUbiquitousContentNameKey: storeName} error:&error];

يعمل مع كافة الإصدارات.قم بتمرير اسم الكيان والتكرار لحذف كافة الإدخالات وحفظ السياق.

func deleteData(entityToFetch: String, completion: @escaping(_ returned: Bool) ->()) {
    var context = NSManagedObjectContext()
    if #available(iOS 10.0, *) {
        context = self.persistentContainer.viewContext
    } else {
        context = self.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)")
    }
}

إليك الإصدار الذي يحذف كل سجل في كل جدول لديك.

سويفت 4

static func resetDatabase() {
    do {
        try dataStore.persistentStoreCoordinator.managedObjectModel.entities.forEach { (entity) in
            if let name = entity.name {
                let fetch = NSFetchRequest<NSFetchRequestResult>(entityName: name)
                let request = NSBatchDeleteRequest(fetchRequest: fetch)
                try mainContext.execute(request)
            }
        }

        try mainContext.save()
    } catch {
        print("error resenting the database: \(error.localizedDescription)")
    }
}

هل تريد حذف ملف المتجر الدائم وإعداد منسق متجر دائم جديد؟

احذف sqlite من fileURLPath ثم قم بالإنشاء.

على افتراض أنك تستخدم MagicalRecord ولديك مخزن ثبات افتراضي:

لا أحب كل الحلول التي تفترض وجود ملفات معينة و/أو تتطلب إدخال أسماء أو فئات الكيانات.هذه طريقة Swift(2)، وهي طريقة آمنة لحذف جميع البيانات من جميع الكيانات.بعد الحذف، سيتم إعادة إنشاء مكدس جديد أيضًا (لست متأكدًا في الواقع من مدى ضرورة هذا الجزء).

إنه جيد لمواقف نمط "تسجيل الخروج" عندما تريد حذف كل شيء ولكن لديك متجر عمل و moc للحصول على بيانات جديدة (بمجرد قيام المستخدم بتسجيل الدخول ...)

extension NSManagedObject {

    class func dropAllData() {

        MagicalRecord.saveWithBlock({ context in

            for name in NSManagedObjectModel.MR_defaultManagedObjectModel().entitiesByName.keys {
                do { try self.deleteAll(name, context: context) }
                catch { print("⚠️ ✏️ Error when deleting \(name): \(error)") }
            }

            }) { done, err in
                MagicalRecord.cleanUp()
                MagicalRecord.setupCoreDataStackWithStoreNamed("myStoreName")
        }
    }

    private class func deleteAll(name: String, context ctx: NSManagedObjectContext) throws {
        let all = NSFetchRequest(entityName: name)
        all.includesPropertyValues = false

        let allObjs = try ctx.executeFetchRequest(all)
        for obj in allObjs {
            obj.MR_deleteEntityInContext(ctx)
        }

    }
}

استخدم هذا

+(NSArray *)fetchDataFromEntity:(NSString *)entityName context:(NSManagedObjectContext *)context
{
    NSFetchRequest * fetchRequest =[[NSFetchRequest alloc] init];
    NSEntityDescription * CategoriesEntity = [NSEntityDescription entityForName:entityName inManagedObjectContext:context];
    [fetchRequest setEntity:CategoriesEntity];

    NSError * error;
    NSInteger count = [context countForFetchRequest:fetchRequest error:&error];

    if (count && count>0) {

        NSArray * fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
        if (fetchedObjects && fetchedObjects.count>0) {

            return fetchedObjects;
        }else
            return nil;

    }
    else
        return nil;
}
+ (void)deleteObjectsOfArray:(NSMutableArray*)ary context:(NSManagedObjectContext *)context {
    for (NSManagedObject * obj in ary) {
        [context deleteObject:obj];
    }
    NSError *saveError = nil;
    [context save:&saveError];
}
+ (void)deleteEntity:(NSString *)entityName context:(NSManagedObjectContext *)context {
    NSArray *listArray = [self fetchDataFromEntity:entityName context:context];
    [self deleteObjectsOfArray:[NSMutableArray arrayWithArray:listArray] context:context];
}

لقد أخذت كود Grouchal ولتسريعه استخدمت التعداد مع الوضع المتزامن (NSEnumerationConcurrent)، لقد أصبح أسرع قليلاً مقارنة بـ for Loop (في تطبيقي أضفت هذه الميزة للمختبرين حتى يتمكنوا من مسح البيانات وإجراء اختبارات بدلاً من حذف التطبيق وتثبيته)

- (void)resetObjects
{
    [self deleteAllObjectsInEntity:@"Entity1"];
    [self deleteAllObjectsInEntity:@"Entity2"];
    [self deleteAllObjectsInEntity:@"Entity3"];
    [self deleteAllObjectsInEntity:@"Entity4"];
}

-(void) deleteAllObjectsInEntity:(NSString*) entityName
{
    MainDataContext *coreDataContext = [MainDataContext sharedInstance];
    NSManagedObjectContext *currentContext = coreDataContext.managedObjectContext;
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:currentContext];
    [fetchRequest setEntity:entity];

    NSError *error;
    NSArray *items = [currentContext executeFetchRequest:fetchRequest error:&error];

    [items enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSManagedObject * obj, NSUInteger idx, BOOL *stop) {
        [currentContext deleteObject:obj];
    }];


    if (![currentContext save:&error]) {
        NSLog(@"Error deleting %@ - error:%@",entityName,error);
    }
}

هنا إصدار Swift3 الخاص بي لحذف جميع السجلات."المستخدمون" هو اسم الكيان

@IBAction func btnDelAll_touchupinside(_ sender: Any) {

    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let managedObjectContext = appDelegate.persistentContainer.viewContext

    let fetchReq = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")
    let req = NSBatchDeleteRequest(fetchRequest: fetchReq)

    do {
        try managedObjectContext.execute(req)

    } catch {
        // Error Handling
    }   
}

iOS 10 وسويفت 3

على افتراض أن اسم الكيان الخاص بك هو "صورة"، وأنك قمت بإنشاء فئة CoreDataStack ...

 func clearData() {
        do {            
            let context = CoreDataStack.sharedInstance.persistentContainer.viewContext
            let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Photo")
            do {
                let objects  = try context.fetch(fetchRequest) as? [NSManagedObject]
                _ = objects.map{$0.map{context.delete($0)}}
                CoreDataStack.sharedInstance.saveContext()
            } catch let error {
                print("ERROR DELETING : \(error)")
            }
        }
    }

فيما يلي برنامج تعليمي جيد لكيفية استخدام CoreData وكيفية استخدام هذه الطريقة.https://medium.com/compileswift/parsing-json-response-and-save-it-in-coredata-step-by-step-fb58fc6ce16f#.1tu6kt8qb

إحدى الطرق الأخرى (بصرف النظر عن طلب الحذف المجمع) التي أستخدمها غالبًا (بناءً على متطلبات التطبيق) هي إعادة تعيين المتجر الدائم.يبدو التنفيذ كما يلي لنظام التشغيل iOS 10+ وSwift (على افتراض أن لديك فئة CoreDataManager):

let persistentContainer: NSPersistentContainer = {
    let container = NSPersistentContainer(name: "<Data-Model-Name>“)
    container.loadPersistentStores(completionHandler: { (storeDescription, err) in
        if let err = err {
            fatalError("loading of store failed: \(err)")
        }
    })
    return container
}()

func resetPersistentStore() {

    if let persistentStore = persistentContainer.persistentStoreCoordinator.persistentStores.last {
        let storeURL = persistentContainer.persistentStoreCoordinator.url(for: persistentStore)

        do {
            try persistentContainer.persistentStoreCoordinator.destroyPersistentStore(at: storeURL, ofType: NSSQLiteStoreType, options: nil)
        } catch {
            print("failed to destroy persistent store:", error.localizedDescription)
        }

        do {
            try persistentContainer.persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeURL, options: nil)
        } catch {
            print("failed to re-add persistent store:", error.localizedDescription)
        }
    }

}

إحدى ميزات هذه الطريقة هي أنها أكثر وضوحًا خاصة عندما يكون لديك الكثير من سجلات البيانات للعديد من الكيانات في بياناتك الأساسية.وفي هذه الحالة، سيكون طلب الحذف الدفعي مستهلكًا للذاكرة.

كلكم تجعلون هذا الأمر يبدو معقدًا.يمكنك فقط إرسال طريقة إعادة التعيين إلى NSManagedObjectContext

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top