核心数据:如何删除不在新数据中的对象

Posted

技术标签:

【中文标题】核心数据:如何删除不在新数据中的对象【英文标题】:Core Data: How to delete objects that are not in new data 【发布时间】:2014-06-30 14:52:42 【问题描述】:

我从针对 ios5 和 iOS7 的斯坦福讲座系列中了解了 Core Data,并且我已经成功地使用 Core Data 制作了 3 个不同的应用程序。但是我一直有一个关于 Core Data 的问题我无法解决:

如果核心数据中的对象不存在于新数据中,是否有办法删除这些对象?

例如,假设我正在开发一个博物馆应用程序。如果 iPhone 中的一些旧的 Core-Data 对象没有出现在从 Internet 接收的新数据中,则意味着这些旧对象在应用程序中不再需要并且应该被删除。你怎么能删除这些?更新和创建新对象很容易,但在 Core Data 中,无法通过消除过程删除对象!

我可以删除所有对象并插入新对象,但每次只修改、更改或删除少数对象。因此,延迟所有内容并再次插入所有内容并不是一个有效的解决方案,尤其是考虑到您每次要获取大约 200 个对象。

【问题讨论】:

【参考方案1】:

假设

您的核心数据实体有一个属性“unique_id”,可以唯一标识每个 对象,以及 服务器响应存储为字典数组(例如来自 JSON 响应) 其中每个字典还包含“unique_id”,

那么您可以执行以下操作:首先,从 来自服务器的新对象:

NSArray *uniqueIds = [serverResponse valueForKey:@"unique_id"];

然后在这个数组中获取所有 ID 不为 的对象。这可以是 使用单个 fetch 请求完成:

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"YourEntity"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT unique_id IN %@", uniqueIds];
request.predicate = predicate;
NSError *error;
NSArray *outdatedObjects = [context executeFetchRequest:request error:&error];
if (outdatedObjects == nil) 
    // handle error ...

最后,删除过期的对象:

for (YourEntity *obj in outdatedObjects) 
    [context deleteObject:obj];

if (![context save:&error]) 
   // handle error ...

【讨论】:

哇,非常感谢。您知道“NOT unique_id IN %@”是如此简单易行。我不知道你能做到这一点。我有一个使用这个解决方案的博物馆应用程序。非常感谢你!真是太感谢你了!! 如果新数据集中有超过 500 000 个唯一实体,则不能使用“NOT unique_id IN %@” @IgorKasuan:你完全正确。但这里“每次只修改、更改或删除少数对象”,对象总数在 200 个左右。【参考方案2】:

您可以获取所有现有对象,遍历它们并检查您获取的对象。如果旧对象不存在,请将其从 CoreData 中删除。这是我在应用程序中的一些伪代码:

    NSMutableSet *objectsToDelete = // Existing CoreData objects
    NSMutableSet *updatedObjects = [NSMutableSet set];

    // Loop over your webservice response objects
    for (...) 
        // Compare to existing objects to check if it's a new object
        // If it is new add it to the updated objects set:
        if (updated) 
        [updatedObjects addObject:webserviceObject];

         else 
            // New object, insert it into CoreData
        
    

    // Calculate deleted objects
    [objectsToDelete minusSet:updatedObjects];
    for (NSManagedObject *obj in objectsToDelete) 
        [obj delete];
    

    // Persist your changes

【讨论】:

非常感谢您的意见。但是,我发现下面的答案更完整,所以我给了它绿色检查。但也为你的+1。我认为这是一个有效的伪代码!

以上是关于核心数据:如何删除不在新数据中的对象的主要内容,如果未能解决你的问题,请参考以下文章

如何从数据数组中删除对象(核心数据)

如何从 iOS 的另一个 nsarray 中不存在的核心数据中删除对象?

如何一次删除多个核心数据对象?

删除核心数据对象时,如何在 Swift 5 中同时删除其所有相关对象?

如何在 swift 3 中从核心数据中删除对象

SWIFT 的核心数据:如何从关系实体中删除对象?