핵심 데이터 : 엔티티의 모든 인스턴스를 삭제하는 가장 빠른 방법


383

핵심 데이터를 사용하여 웹 서비스 호출의 결과를 로컬로 유지하고 있습니다. 웹 서비스는 "Cars"에 대해 전체 객체 모델을 반환합니다. "Cars"는 약 2000 개가 될 수 있습니다 (웹 서비스가 1 개 또는 모든 자동차보다 작은 값을 반환하도록 할 수는 없습니다).

다음에 응용 프로그램을 열 때 모든 자동차에 대해 웹 서비스를 다시 호출하여 Core Data 지속 복사본을 새로 고치려고하지만 중복을 방지하려면 먼저 로컬 캐시의 모든 데이터를 제거해야합니다.

관리 객체 컨텍스트 (예 : "CAR"유형의 모든 엔터티)에서 특정 엔터티의 모든 인스턴스를 제거하는 더 빠른 방법이 있습니까? 아니면 쿼리를 호출 한 다음 결과를 반복하여 각 인스턴스를 삭제 한 다음 저장해야합니까?

이상적으로 엔티티가 Blah 인 모든 것을 삭제한다고 말할 수 있습니다.


인 메모리 데이터베이스를 사용할 수 있습니다
J. Doe

답변:


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
}

목표 -C

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 만 검색하도록 페치를 구성합니다.
Marcus S. Zarra

38
NSMangagedObjectID 만 가져 오는 방법은 확실하지 않습니다. use [allCars setIncludesPropertyValues ​​: NO]; (그리고 객체 ID에 대한 NSPropertyDescription을 만드는 방법에 대한 사냥을 귀찮게하지 마십시오!)
ohhorob

6
초보자 질문 죄송합니다 : for 루프가 끝난 후 컨텍스트를 저장해야합니까? 예를 들어 [myContext save];
Steve

6
이것을 더욱 효율적으로 만들기 위해 Core Data에 새로운 시설이 있습니까? 이것은 내 앱이 이미 Core Data로 포팅하는 길에 심각한 문제입니다. 여러 테이블 중 하나에서 4000 항목을 모두 삭제하는 데 몇 초가 걸립니다. 사용자가 기다리는 시간이 너무 깁니다. sqlite와 직접 동일한 요청이 즉각적인 것 같습니다.
David

4
@DaveDeLong NSBatchDeleteRequest가 어떻게 NSFetchedResultsController 델리게이트를 트리거 할 수 있습니까? 나는 거의 모든 것을 시도하지만 아무 일도 일어나지 않습니다.
Foriger

36

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

조금 더 깨끗하고 보편적 인 방법 :이 방법을 추가하십시오 :

- (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
이 답변은 새로운 try / catch 오류 처리
Suragch

10

이것은 하나에 비슷한 질문입니다 여기에 누군가 당신이 하나의 개체를 삭제해야하므로 관계 삭제 규칙을 설정 제안했다. 따라서 자동차와 많은 관계가있는 엔터티를 가지고 있거나 만들 수 있고 더 높은 엔터티를 삭제할 때 삭제 규칙을 계단식으로 설정하면 모든 자동차도 삭제됩니다. 모든 차량 적재와 관련된 단계를 수행 할 필요가 없으므로 처리 시간이 절약 될 수 있습니다. 더 큰 데이터 세트에서는 이것이 절대적으로 필요할 수 있습니다.


1
방금 현재 프로젝트에서 약 600 개의 핵심 데이터 객체로 시도했습니다. 캐스케이드를 사용하여 다른 객체에 캡슐화하면 삭제하는 데 약 9.1 초가 걸렸습니다. Dave가 제안한 방법을 사용하면 삭제하는 데 약 8.7 초가 걸립니다. 나에게 눈에 띄는 차이는 없습니다.
Andrew Zimmer

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

... 당신이해야 할 유일한 것은 app delegate에서 managedObjectContext를 가져 오는 것입니다.

나중에 다음과 같이 사용할 수 있습니다.

[NSManagedObject deleteAllFromEntity:@"EntityName"];

하나의 추가 최적화는 tha entityname에 대한 매개 변수를 제거하고 clazzname에서 대신 이름을 얻는 것입니다. 이것은 사용법으로 이어질 것입니다 :

[ClazzName deleteAllFromEntity];

보다 깨끗한 impl (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]반드시 "깨끗한 아키텍처"는 아닙니다 .. ;-)
Daniel Rinser

알았어 위의 코드는 하나의 managedObjectContext를 기반으로합니다. 기본 코드;) 다중 스레드 코드에서 나는 보통 앱 델리게이트의 주요 MOC를 다른 사람과 병합합니다
Erhard Dinhobl

1
@DanielRinser 수deleteAllFromEntity: inManagedObjectContext:
모하메드 Elkassas

예. deleteAllFromEntity 메소드를 클래스 메소드에서 오브젝트 메소드로 변경하는 것이 좋습니다. 그런 다음 MOC 인스턴스에서 deleteAllFromEntity를 직접 호출 할 수 있습니다.
Erhard Dinhobl

7

스위프트 4, iOS 12 및 Xcode 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 개념이 작동하지 않는 이유는 무엇입니까? 어떤 생각.
Suresh Durishetti

@SureshDurishetti 클래스에서 CoreData를 가져 왔습니까?
Xcodian Solangi

1
예, CoreDate가 추가되었습니다. 그러나 운이 없다.
Suresh Durishetti

4
당신은 문맥에 통화 저장을 추가하는 것을 잊어 버렸습니다. context.save ()를 추가하면 좋습니다.
Parama Dharmika

네, 그렇지 않으면 아무런 변화가 일어나지 않습니다 컨텍스트를 저장해야
렌드 라 쿠마

5

스위프트 3.X스위프트 4.X , 쉬운 방법. 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)")
    }

또한 당신은이 구성을 사용할 수 있습니다 : let fetchRequest : 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
답변을 게시 해 주셔서 감사합니다. 그것은 나를 위해 작동합니다. 그러나 여기에 코드를 복사하여 붙여 넣지 마십시오. 새로운 꿀벌의 경우 자신 CoreDataStack()이나 DataController()수업이 무엇인지 명확하지 않습니다 . ;)
Nico S.

4

Dave Delong의 답변 연장.

iOS 9 및 이전 버전을 처리하는 Swift 버전. 나는 또한 이것의 오류 처리를 다루었 다.

appDelegate를 보자 : AppDelegate = UIApplication.sharedApplication (). delegate as! 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 방법은 실제로 awsm입니다.
Shobhakar Tiwari

2

기존 캐시로 수신 한 데이터를 접어보십시오. 그렇지 않으면 실제로 '새로 고침'이 아니며 '다시 시작'이며 SQLLite 파일을 삭제 / 삭제하고 다시 시작할 수 있습니다 (다른 데이터도 유지하지 않는다고 가정).


1
나쁜 해결책. Sqlite 데이터베이스에 다른 테이블이 있으면 분명히 모든 테이블을 풉니 다. 이것은 특정 솔루션에 대한 해킹이며 더 큰 경우에는 고려할 수 없습니다.
Deepak GM

2

Swift 4, iOS 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 (entityName : String (describing : self))로 대체되었습니다.


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

Dave Delongs의 Swift 2.0 답변이 저에게 충돌했습니다 (iOS 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'및 'NSManagedObjectContext'의 확장으로 구현 된 이전 iOS 버전으로 대체되는 Swift 3 솔루션 애플 레퍼런스 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 save를 실행하고, 그렇지 않으면 NSFetchRequest를 사용하여 레코드를 가져오고 for 루프의 모든 레코드를 삭제하고 삭제가 완료되면 저장하십시오.


0

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

실행 후 reset을 호출해야합니다. 그렇지 않은 경우 테이블보기에서 업데이트되지 않습니다.


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

그런 다음 do / catch 블록을 호출하십시오.

    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)")
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.