1

考虑提要中的字典对象与核心数据中的排序实体之间的以下相关性:

Feed  CoreData
----  --------
A     A
B     B
C     C
D     D

在枚举提要时,我检查实体中是否有 A 的[stringForKey:@"name"]isEqualTo A.name。如果匹配,我会更新实体。如果不是,我在 CoreData 中插入一个新实体。

这适用于更新和插入,但不适用于删除。考虑从提要中删除对象 C:

Feed  CoreData
----  --------
A     A
B     B
D     C
      D

当我到达提要中的“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

这一定是一个常见问题,所以我想知道确定何时从核心数据中删除实体的最佳实践是什么。

4

2 回答 2

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);
}
于 2013-06-17T20:42:53.223 回答
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++;
}

在您的示例中:

    饲料核心数据
    ---- --------
i1->A i2->同名,CoreData对象更新,i1++,i2++
    BB
    直流
              D
    饲料核心数据
    ---- --------
    AA
i1->B i2->B同名,CoreData对象更新,i1++,i2++
    直流
              D
    饲料核心数据
    ---- --------
    AA
    BB
i1->D i2->C "D" > "C",CoreData对象被删除,i2++
              D
    饲料核心数据
    ---- --------
    AA
    BB
i1->直流
          i2->D同名,CoreData对象更新,i1++,i2++
于 2013-06-17T21:39:56.817 回答