【问题标题】:CoreData delete multiple objectsCoreData 删除多个对象
【发布时间】:2013-01-11 17:23:18
【问题描述】:

我知道如何删除 CoreData 中的单个对象我只是想知道是否有更简单的方法来删除多个对象?

对于单个删除,您可以使用

[moc deleteObject:someManagedObject];

但对于多个对象没有等效项。

目前我正在考虑做...

NSArray *arrayOfManagedObjectsToDelete = //...

for (SomeManagedObjectClass *managedObject in arrayOfManagedObjectsToDelete) {
    [moc deleteObject:managedObject];
}

但我不确定是否有其他方法可以做到这一点?

理想的方法是...

- (void)deleteObjects:(NSSet*)objects

NSManagedObjectContext 或一些类似的方法上。

【问题讨论】:

标签: ios objective-c core-data


【解决方案1】:

据我所知,没有一种方法可以做到这一点......你应该像你已经在做的那样做。有一个名为 deletedObjects 的方法,但它只返回一组对象,这些对象将在下一次保存操作期间从其持久存储中删除,如类参考中所述。

【讨论】:

  • 谢谢,我想可能是这样。我只是想检查一下我没有遗漏什么。
【解决方案2】:

不,没有特定的方法可以删除多个对象 atm。但我会做这样的事情,类似于你已经在做的事情:

- (void)removeFromManagedObjectContext {
  NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    fetchRequest.entity = [NSEntityDescription entityForName:@"YourEntity" inManagedObjectContext:managedObjectContext];

    NSArray *results = [managedObjectContext executeFetchRequest:fetchRequest error:nil];

 
  
    for (Your Entity *Entity in results) {
        [managedObjectContext deleteObject:Entity];
    }
}

【讨论】:

    【解决方案3】:

    iOS 9

    斯威夫特

    let fetchRequest = NSFetchRequest(entityName: "EntityName") let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
    
    do {
        try myPersistentStoreCoordinator.executeRequest(deleteRequest, withContext: myContext) } catch let error as NSError {
        // TODO: handle the error 
    }
    

    Objective-C

    NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"EntityName"];
    NSBatchDeleteRequest *deleteRq = [[NSBatchDeleteRequest alloc] initWithFetchRequest:request];
    
    NSError *deleteError = nil;
    [myPersistentStoreCoordinator executeRequest:deleteRq withContext:myContext error:&deleteError];
    

    iOS 8 及更早版本

    NSFetchRequest *fr = [[NSFetchRequest alloc] init];
    [fr setEntity:[NSEntityDescription entityForName:@"EntityName" inManagedObjectContext:myContext]];
    [fr setIncludesPropertyValues:NO]; //only fetch the managedObjectID
    
    NSError *error = nil;
    NSArray *objects = [myContext executeFetchRequest:fr error:&error];
    
    //error handling goes here
    for (NSManagedObject *object in objects) {
      [myContext deleteObject:object];
    }
    NSError *saveError = nil;
    [myContext save:&saveError];
    //more error handling here
    

    【讨论】:

    • 如果我们有私人NSManagedObjectContext,是否可以在后台执行NSOperation? (我们通过它的属性persistentStoreCoordinator从该上下文中获取persistentStoreCoordinator)
    • 可以,只要您像对待其他 MOC 变更一样关注合并变更政策。
    • 这会删除所有对象,问题是如何删除几个项目。
    • iOS 9 的例子似乎忽略了级联删除规则。
    • 请注意,NSBatchDeleteRequest 不会触发通知,您还应该在它之后使上下文无效,因为它直接更改存储...
    【解决方案4】:

    iOS10 & Swift 3

        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "EntityName")
        let deleteRequest = NSBatchDeleteRequest( fetchRequest: fetchRequest)
    
        do{
            try mContext.execute(deleteRequest)
        }catch let error as NSError {//handle error here }
    

    这会删除EntityName 的所有对象,但您可以使用NSPredicate 应用额外的过滤

    【讨论】:

    • @Fogmeister,我发布这个的原因是当前排名最高的答案没有在 Swift 3 和 iOS 10 中构建。另外,在我看来,在 NSManagedObjectContext 上调用该方法更可取。跨度>
    • 抱歉,我投反对票太快了。我认为这是通常的“这是另一个答案,但略微更改为 Swift 3”类型的答案。现在接受这个答案,因为它实际上改进了当前答案。谢谢:D
    • 请注意,NSBatchDeleteRequest 不会触发通知,您还应该在它之后使上下文无效,因为它直接更改存储...
    【解决方案5】:

    来自https://www.avanderlee.com/swift/nsbatchdeleterequest-core-data/

    extension NSManagedObjectContext {
        
        /// Executes the given `NSBatchDeleteRequest` and directly merges the changes to bring the given managed object context up to date.
        ///
        /// - Parameter batchDeleteRequest: The `NSBatchDeleteRequest` to execute.
        /// - Throws: An error if anything went wrong executing the batch deletion.
        public func executeAndMergeChanges(using batchDeleteRequest: NSBatchDeleteRequest) throws {
            batchDeleteRequest.resultType = .resultTypeObjectIDs
            let result = try execute(batchDeleteRequest) as? NSBatchDeleteResult
            let changes: [AnyHashable: Any] = [NSDeletedObjectsKey: result?.result as? [NSManagedObjectID] ?? []]
            NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [self])
        }
    }
    

    我的目标是删除一些对象,所以这是我的使用方法

    var objectsToRemove = [NSManagedObjectID]()
    // gather objectIDs
    
    let batchDeleteRequest = NSBatchDeleteRequest(objectIDs: objectsToRemove)
    do {
        try defaultContext.executeAndMergeChanges(using: batchDeleteRequest)            
    } catch {
        // handle error
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      相关资源
      最近更新 更多