考虑Feed中的字典对象与核心数据中的已排序实体之间的以下相关性:
Feed CoreData
---- --------
A A
B B
C C
D D
在我枚举Feed时,我会检查实体中的A [stringForKey:@"name"]
是否等于A.name
。如果匹配,我更新实体。如果不是,我将一个新实体插入CoreData。
这适用于更新和插入,但不适用于删除。考虑从Feed中删除对象C:
Feed CoreData
---- --------
A A
B B
D C
D
当我在Feed中找到“D”时,它会看到CoreData中的对象“C”不匹配并创建一个新对象D.所以我现在有两个问题:我有两个“D”对象,和对象“C”不会从CoreData中删除。
所以,虽然我想最终得到这个:
Feed CoreData
---- --------
A A
B B
D D
我目前得到的是:
Feed CoreData
---- --------
A A
B B
D C
D
D
这一定是一个常见问题,所以我想知道什么是最佳做法,以确定何时从Core Data中删除实体。
答案 0 :(得分:2)
当我遍历项目以确定是否更新,插入或删除时,我就会这样做:
-(void)updateWithJSON:(id)JSON
{
//Get an array of all related managed objects
NSMutableArray *allContacts = [[NSMutableArray alloc] initWithArray:[self getAllContacts]];
//Loop through each object downloaded from the server
for (NSDictionary *objectInfo in [JSON objectForKey:@"Contacts"])
{
NSString *objectKey = [objectInfo objectForKey:@"BackendID"];
//Get the managed object for the objectKey
Contact *contact = [[allContacts filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"backendID == %@", objectKey]] lastObject];
//If the object is nil, then insert the object
if (contact == nil)
{
NSLog(@"Object with key %@ is new.", objectKey);
contact = [[Contact alloc] initWithEntity:[NSEntityDescription entityForName:@"Contact" inManagedObjectContext:self.managedObjectContext] insertIntoManagedObjectContext:self.managedObjectContext];
contact.backendID = objectKey;
}
//Assign property values
contact.firstName = [objectInfo objectForKey:@"FirstName"];
contact.lastName = [objectInfo objectForKey:@"LastName"];
contact.jobTitle = [objectInfo objectForKey:@"JobTitle"];
contact.department = [objectInfo objectForKey:@"Department"];
contact.email = [objectInfo objectForKey:@"Email"];
contact.fax = [objectInfo objectForKey:@"Fax"];
contact.primaryPhone = [objectInfo objectForKey:@"PrimaryPhone"];
contact.secondaryPhone = [objectInfo objectForKey:@"SecondaryPhone"];
//Remove the object from the array of all the objects
if ([allContacts containsObject:contact])
[allContacts removeObject:contact];
}
//Delete any objects that still remain in the array (means they were deleted server-side
for (Contact *contact in allContacts) {
NSLog(@"Removing Contact with key %@", contact.backendID);
[self.managedObjectContext deleteObject:contact];
}
NSError *error = nil;
[self.managedObjectContext processPendingChanges];
[self.managedObjectContext save:&error];
if (error)
NSLog(@"Error Saving Contacts: %@", error.localizedDescription);
}
答案 1 :(得分:1)
看起来,你已经拥有了一个Feed对象数组和一个CoreData对象数组 按升序排列相同的属性“名称”。
您可以使用单个循环从Feed对象更新/插入/删除CoreData对象 在两个数组中使用两个独立指针进入数组。
伪代码如下所示:
i1 = 0; // pointer into Feed array
i2 = 0; // pointer into CD (CoreData objects) array
while (i1 < Feed.count && i2 < CD.count) {
if (Feed[i1].name < CD[i2].name) {
// Feed[i1] is not in CD array
"Insert Feed[i1] as new Core Data object"
i1++;
} else if (Feed[i1].name > CD[i2].name) {
// CD[i2].name is not in Feed array
"Delete CD[i2] from Core Data"
i2++;
} else {
"Update CD[i2] from Feed[i1]"
i1++, i2++;
}
}
// Add remaining objects from Feed array:
while (i1 < Feed.count) {
"Insert Feed[i1] as new Core Data object"
i1++;
}
// Remove remaining Core Data objects
while (i2 < CD.count) {
"Delete CD[i2] from Core Data"
i2++;
}
在你的例子中:
Feed CoreData ---- -------- i1->A i2->A same name, CoreData object is updated, i1++, i2++ B B D C D
Feed CoreData ---- -------- A A i1->B i2->B same name, CoreData object is updated, i1++, i2++ D C D
Feed CoreData ---- -------- A A B B i1->D i2->C "D" > "C", CoreData object is deleted, i2++ D
Feed CoreData ---- -------- A A B B i1->D C i2->D same name, CoreData object is updated, i1++, i2++