Dữ liệu cốt lõi: Cách nhanh nhất để xóa tất cả các phiên bản của một thực thể


383

Tôi đang sử dụng Dữ liệu lõi để duy trì kết quả cục bộ từ cuộc gọi Dịch vụ web. Dịch vụ web trả về mô hình đối tượng đầy đủ cho, giả sử, "Ô tô" - có thể là khoảng 2000 trong số chúng (và tôi không thể khiến Dịch vụ web trả lại bất cứ thứ gì dưới 1 hoặc TẤT CẢ ô tô.

Lần sau khi tôi mở ứng dụng, tôi muốn làm mới bản sao vẫn tồn tại của Dữ liệu lõi bằng cách gọi lại Dịch vụ web cho tất cả các Xe, tuy nhiên để tránh trùng lặp, trước tiên tôi cần phải xóa tất cả dữ liệu trong bộ đệm cục bộ.

Có cách nào nhanh hơn để thanh lọc TẤT CẢ các thực thể của một thực thể cụ thể trong ngữ cảnh đối tượng được quản lý (ví dụ: tất cả các thực thể loại "CAR") hay tôi cần truy vấn chúng gọi, sau đó lặp qua các kết quả để xóa từng thực thể, sau đó lưu lại?

Lý tưởng nhất là tôi có thể nói xóa tất cả nơi thực thể là Blah.


Bạn có thể sử dụng cơ sở dữ liệu trong bộ nhớ
J. Doe

Câu trả lời:


718

iOS 9 trở lên:

iOS 9 đã thêm một lớp mới được gọi là NSBatchDeleteRequestcho phép bạn dễ dàng xóa các đối tượng khớp với một vị từ mà không phải tải tất cả chúng vào bộ nhớ. Đây là cách bạn sử dụng nó:

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

Mục tiêu-C

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

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

Thông tin thêm về việc xóa hàng loạt có thể được tìm thấy trong phiên "Có gì mới trong dữ liệu cốt lõi" từ WWDC 2015 (bắt đầu từ ~ 14: 10).

iOS 8 trở về trước:

Tìm nạp tất cả và xóa tất cả:

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
Tôi cũng sẽ định cấu hình tìm nạp để chỉ truy xuất NSManagedObjectID để giảm bất kỳ chi phí nào khi tải trong cấu trúc đối tượng đầy đủ.
Marcus S. Zarra

38
Không rõ ràng làm thế nào để chỉ tìm nạp NSMangagedObjectID .. sử dụng [allCars setIncludesPropertyValues: NO]; (và đừng bận tâm tìm kiếm cách tạo NSPropertyDes mô tả cho ID đối tượng!)
ohhorob

6
xin lỗi cho câu hỏi của người mới: bạn có cần lưu bối cảnh sau khi kết thúc vòng lặp for không? ví dụ: [myContext save];
Steve

6
Bất kỳ cơ sở mới trong Core Data để làm cho điều này hiệu quả hơn? Đây là một vấn đề nghiêm trọng đối với ứng dụng của tôi đã đi xa tới việc chuyển sang Core Data. Mất nhiều giây để xóa tất cả 4000 mục từ chỉ một trong nhiều bảng. Điều này là quá lâu để người dùng chờ đợi. Cùng một yêu cầu trực tiếp với sqlite dường như ngay lập tức.
David

4
@DaveDeLong Làm thế nào NSBatchDeleteRequest có thể kích hoạt đại biểu NSFetchedResultsControll? Tôi thử hầu hết mọi thứ, nhưng không có gì xảy ra.
Foriger

36

Đặt lại thực thể trong 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")
        }
    }

32

Một chút sạch sẽ và phổ quát hơn: Thêm phương pháp này:

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

Đối với 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")
  }
}

12

Nhanh:

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
Câu trả lời này cần được cập nhật với cách xử lý lỗi thử / bắt mới
Suragch

10

Đây là một câu hỏi tương tự như câu hỏi ở đây và ai đó đề nghị thiết lập quy tắc xóa mối quan hệ để bạn chỉ phải xóa một đối tượng. Vì vậy, nếu bạn có hoặc có thể tạo một thực thể có mối quan hệ với nhiều ô tô và đặt quy tắc xóa thành xếp tầng khi bạn xóa thực thể cao hơn, tất cả các ô tô cũng sẽ bị xóa. Điều này có thể tiết kiệm một số thời gian xử lý vì bạn không phải thực hiện các bước liên quan đến việc tải TẤT CẢ các xe. Trong một tập dữ liệu lớn hơn, điều này có thể thực sự cần thiết.


1
Tôi vừa thử điều này trong dự án hiện tại của tôi với khoảng 600 đối tượng dữ liệu cốt lõi. Khi tôi gói chúng trong một đối tượng khác bằng tầng, mất khoảng 9,1 giây để xóa. Nếu tôi sử dụng phương pháp được Dave đề xuất về thì sẽ mất khoảng 8,7 giây để xóa. Không phải là một sự khác biệt đáng chú ý đối với tôi.
Andrew Zimmer

8

Một câu trả lời tốt đã được đăng, đây chỉ là một khuyến nghị!

Một cách tốt là chỉ cần thêm một danh mục NSManagedObjectvà thực hiện một phương pháp như tôi đã làm:

Tệp tiêu đề (ví dụ NSManagedObject+Ext.h)

@interface NSManagedObject (Logic)

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

@end

Mã tệp: (ví dụ: 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

... điều duy nhất bạn phải làm là có được ManagedObjectContext từ đại biểu ứng dụng hoặc nơi bạn có nó;)

Sau đó, bạn có thể sử dụng nó như:

[NSManagedObject deleteAllFromEntity:@"EntityName"];

một tối ưu hóa nữa có thể là bạn loại bỏ tham số cho tha thực thể và lấy tên thay vì từ clazzname. điều này sẽ dẫn đến việc sử dụng:

[ClazzName deleteAllFromEntity];

một hàm sạch hơn (như thể loại cho 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

Việc sử dụng sau đó:

[managedObjectContext deleteAllFromEntity:@"EntityName"];

1
Xin lỗi, nhưng [AppDelegate managedObjectContext]không nhất thiết là một "kiến trúc sạch" .. ;-)
Daniel Rinser 6/03/2015

Ok, đúng rồi. Mã của nó ở trên được dựa trên một ManagedObjectContext. mã chính;) Trong mã đa luồng, tôi thường hợp nhất MOC chính của đại biểu ứng dụng cho các ứng dụng khác
Erhard Dinhobl

1
@DanielRinser có thểdeleteAllFromEntity: inManagedObjectContext:
Mohamed Elkassas

Đúng. Tốt hơn là thay đổi phương thức xóa ALLFromEntity từ phương thức lớp sang phương thức đối tượng. sau đó bạn có thể gọi trực tiếp xóa ALLFromEntity trên một cá thể MOC.
Erhard Dinhobl

7

Cập nhật Swift 4, iOS 12 và Xcode 10

100% làm việc chỉ cần cắt và dán

Chỉ cần đặt chức năng này trong lớp có liên quan và gọi chức năng này self.deleteData()trong viewDidLoad()hoặc bất kỳ nơi nào hoặc dưới chức năng hoặc nút để bằng cách nhấp vào nút, tất cả dữ liệu từ thực thể sẽ bị xóa và thay thế "myEntity" là thực thể mà bạn đã xác định trong dữ liệu cốt lõi

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

Cảm ơn bạn, nhưng tại sao khái niệm os NSBatchDeleteRequest không hoạt động? bất kỳ ý tưởng.
Suresh Durishetti

@SureshDurishetti bạn đã nhập CoreData trong lớp chưa?
Xcodian Solangi

1
Có, đã thêm CoreDate. Nhưng không có may mắn.
Suresh Durishetti

4
Bạn đã quên thêm lưu cuộc gọi vào ngữ cảnh, thêm bối cảnh.save () và bạn vẫn ổn
Parama Dharmika 30/03/18

Có, điều này đòi hỏi phải lưu bối cảnh nếu không sẽ không có thay đổi
Surendra Kumar

5

Swift 3.XSwift 4.X , Cách dễ dàng. Chỉ thay đổi 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)")
    }

Ngoài ra, bạn có thể sử dụng cấu trúc này: let fetchRequest: NSFetchRequest <NSFetchRequestResult> = YourTable.fetchRequest ()
Daniil

5

iOS 10 trở lên

Hoạt động với tất cả các phiên bản. Truyền tên thực thể và lặp qua để xóa tất cả các mục và lưu bối cảnh.

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
Cảm ơn đã gửi câu trả lời của bạn. Nó ổn với tôi. Nhưng bạn không nên chỉ sao chép và dán mã của bạn ở đây. Đối với một newbee, không rõ bạn CoreDataStack()hoặc DataController()lớp học của bạn là gì. Một bản cập nhật sẽ được đánh giá cao;)
Nico S.

4

Mở rộng câu trả lời của Dave Delong.

Phiên bản Swift cũng chăm sóc iOS 9 và các phiên bản trước đó. Tôi cũng đã đề cập đến việc xử lý Lỗi trong việc này:

hãy để appDelegate: AppDelegate = UIApplication. SharedApplication (). ủy nhiệm như! Ứng viên

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

nâng cao. ios 9 cách xóa hồ sơ là thực sự tuyệt vời.
Shobhakar Tiwari

2

Tại sao không gấp trong dữ liệu mà bạn nhận được với bộ đệm hiện có? Mặt khác, nó không thực sự 'làm mới', đó là 'bắt đầu lại' và bạn cũng có thể thả / xóa tệp SQLLite và bắt đầu lại (giả sử bạn cũng không lưu giữ dữ liệu khác).


1
Giải pháp xấu. Nếu có các bảng khác trong cơ sở dữ liệu Sqlite, rõ ràng chúng ta sẽ mất tất cả. Đây là một hack cho một giải pháp cụ thể và không thể được xem xét cho các trường hợp lớn hơn.
Deepak GM

2


Hàm Swift 4, iOS 10+ có thể áp dụng cho mọi thực thể để xóa tất cả dữ liệu của nó

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

'Phòng' là một thực thể

Room.removeAllObjectsInContext(self.persistentContainer.viewContext)

Được chỉnh sửa vào năm 20191025: hướng dẫn "Self.fetchRequest ()" có thể gây ra sự cố nếu chúng tôi sử dụng nhiều mục tiêu trong cùng một dự án. Vì vậy, được thay thế bằng NSFetchRequest (entityName: String (mô tả: self))


1

Nếu thực thể chứa nhiều mục, cách tốt nhất là như thế này vì nó tiết kiệm bộ nhớ

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

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

1

Mã này sẽ hoạt động cho cả iOS 9 trở xuống

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 trở lên:

NSBatchDeleteRequestđược sử dụng để xóa các bản ghi trong dữ liệu cốt lõi. Nó hoạt động rất nhanh và mất ít thời gian hơn để xóa tất cả các bản ghi khỏi một thực thể. Nó đòi hỏi NSFetchRequesttrong tranh luận. Nếu bạn muốn xóa tất cả các bản ghi khỏi một thực thể, bạn có thể sử dụng nó và nó hoạt động với tôi.

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

thanh lọc nhanh tất cả các đối tượng trong 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

Câu trả lời Swift 2.0 của Dave Delongs đã bị sập đối với tôi (trong iOS 9)

Nhưng điều này đã làm việc:

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

Giải pháp Swift 3 với iOS 9 'NSBatchDeleteRequest' và dự phòng cho các phiên bản iOS trước đó được triển khai dưới dạng tiện ích mở rộng trên 'NSManagedObjectContext'. Tài liệu tham khảo của Apple https://developer.apple.com/l 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

Sử dụng NSBatchDeleteRequest để xóa nhiều bản ghi Nếu iOS tối thiểu là 9.0. Nếu luồng nền, thực thi NSManagedObjectContext lưu khác sử dụng NSFetchRequest để lấy bản ghi và xóa tất cả các bản ghi trong vòng lặp và Lưu sau khi xóa xong.


0

trong iOS 11.3 và 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)")
        }

bạn phải gọi lại sau khi bạn thực hiện. Nếu không, nó sẽ không cập nhật trên giao diện bảng.


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

cách OOP không có bất kỳ chuỗi nào như tên thực thể 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
    }
}

sau đó chỉ cần gọi trong khối bắt / bắt

    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

Trong 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)")
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.