如何在核心数据中以一对多关系对单元格进行重新排序

时间:2012-10-31 10:32:17

标签: ios ios5 core-data nsorderedset

我正在学习coreData我是新人,我创建了一个一对多的老板和员工关系(即一个老板和许多员工)。所以我在firstTableView上显示所有老板,当用户点击单元格时,他可以查看分配给每个老板的员工,也可以将员工添加到任何特定老板。 现在我想重新排序老板细胞。那应该怎么做呢?

根据以下讨论进行编辑

   - (void)insertNewObject:(NSString *)fileName
{    
    Boss *bossName = [NSEntityDescription insertNewObjectForEntityForName:@"Boss" inManagedObjectContext:self.managedObjectContext];

    [bossName setName:fileName];

    NSManagedObject *lastObject = [self.controller.fetchedObjects lastObject];
    float lastObjectDisplayOrder = [[lastObject valueForKey:@"displayOrder"] floatValue];
    NSLog(@"%f",lastObjectDisplayOrder);
    [bossName setValue:[NSNumber numberWithDouble:lastObjectDisplayOrder + 1.0] forKey:@"displayOrder"];

    // Save the context.
    NSError *error = nil;
    if (![self.managedObjectContext save:&error]) {
        // Replace this implementation with code to handle the error appropriately.
        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
}

1 个答案:

答案 0 :(得分:1)

[更新问题的具体答案]

它要么......

[self.boss insertObject:newEmployeeObject inEmployeesAtIndex:0];

如果您选择从模型中创建子类,那么这是一个核心数据生成方法,它是Boss子类的一部分。或....

NSMutableOrderedSet *employees = [self.boss mutableOrderedSetValueForKey:@"employees"];
[employees insertObject:newEmployee atIndex:0]

我知道,这不是直观的,你不能只制作一个可变副本,你必须从mutableOrderedSetValueForKey获得一个特殊的代理对象。


[原始一般答案] ......

核心数据现在可以使用您可以在模型中指定的“有序关系”。如果这样做,对象模型中的关系将由新类NSOrderedSet表示,该类是NSArrayNSSet的混合。通过重新排序此关系对象中的对象并保存上下文,您将重新排序数据库中的对象,并且它们将保持新的顺序。当对象上没有自然排序属性时,往往会使用这种有序关系。例如,订单仅表示用户在UI中排序列表的首选项。

另一方面,如果您的某个对象上有一个属性来描述集合的顺序,那么您可以使用该属性通过指定Sort Descriptors来对NSFetchRequest的结果进行排序。属性的值将指定对象在NSFetchRequest的结果中所处的位置。

如果您使用Ordered Relationships,则需要保持该关系NSOrderedSet的顺序,同步UITableView。如果更改是从UI驱动的,那么您将响应UITableViewDataSource委托方法,例如- (void)moveRowAtIndex:(NSUInteger)sourceIndex toIndex:(NSUInteger)destinationIndex,并使用提供的信息将相应的对象移动到核心数据关系中的新位置,方法是使用来自mutableOrderedSetValueForKey:的代理对象或生成的子类的核心数据生成的访问器。

如果订单更改是从数据方面驱动的,您可以使用UITableView上的方法,例如insertRowsAtIndexPaths:withRowAnimation:moveRowAtIndexPath:toIndexPath:来同步UITableView中的行您在数据中所做的更改。

如果您使用的是NSFetchRequest,则您有类似的任务。在这种情况下,您可以通过更新对象的排序属性来响应订单中用户驱动的更改,以匹配UITableView通过UITableViewDataSource委托描述的新订单。或者,如果订单更改从数据端开始,则通过它的方法更新UITableView,以使您对数据的排序属性所做的更改相匹配。在这种情况下,您将使用NSFetchResults作为NSArray的结果,您还必须保持该对象同步,直到您下次运行NSFetchRequest为止。您可以使用相同的排序描述符对数组进行排序,或创建NSMutableArray并使用它的方法移动数据以匹配表。

最后,如果您使用的是NSFetchRequest,您可能希望查看NSFetchedResultsController这是简化同步已排序的NSFetchRequestUITableView的任务的工作。文档中有很好的示例代码。在这种情况下,您可能会发现数据的排序将自行处理。例如,假设您的表按“分配日期”(即员工分配给老板的日期)排序,然后只需使用正确的信息创建对象,就会在表格中触发正确的结果。

请注意,有序关系不适用于iCloud。但是在我看来,iCloud无论如何都不起作用,所以这不是问题。