如果从Feed中删除了Core Data中的对象

时间:2013-06-17 20:26:48

标签: ios core-data nsenumerator

考虑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中删除实体。

2 个答案:

答案 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++