遍历 iOS Core Data 关系

Posted

技术标签:

【中文标题】遍历 iOS Core Data 关系【英文标题】:Iterate through iOS Core Data relationship 【发布时间】:2012-04-09 16:02:53 【问题描述】:

我正在玩一个可以跟踪人们何时收到出版物的应用。 我有两个核心数据实体,publication 和 person,它们之间有一对多的关系,因为每个实体都可以有很多其他的关系。 发布 > 人。

我正在尝试遍历关系,以便如果一个人收到了出版物,则单元格应该是样式复选标记。如果他们没有,那么它应该是单元格样式。这是我目前所拥有的:

-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath 

    Person *personForCell = (Person *) [fetchedResultsController objectAtIndexPath:indexPath];
    cell.textLabel.text = [NSString stringWithFormat:@"%@ %@", personForCell.firstName, personForCell.lastName];


    NSArray *issuesForPersonArray = [personForCell.issues allObjects];

    if ([issuesForPersonArray count] != 0) 

    for (int i = 0; i <= [issuesForPersonArray count]; i++) 
        if ([issuesForPersonArray objectAtIndex:i] == km) 
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
        else 
            cell.accessoryType = UITableViewCellAccessoryNone;
        
    

当我运行它时,只要没有人与此出版物有关系,它就会显示所有人。但是一旦我选择了他们的名字,我就会得到这个日志:

由于未捕获的异常“NSRangeException”而终止应用程序,原因: '* -[__NSArrayI objectAtIndex:]: 索引 1 超出范围 [0 .. 0]'

这里是 didSelectRow 方法:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

    [tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:NO];
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if (cell.accessoryType == UITableViewCellAccessoryNone) 
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        // Reflect selection in data model
        Person *personSelected = (Person *) [fetchedResultsController objectAtIndexPath:indexPath];
        [publication addPersonObject:personSelected];


     else if (cell.accessoryType == UITableViewCellAccessoryCheckmark) 
        cell.accessoryType = UITableViewCellAccessoryNone;
        // Reflect deselection in data model
        Person *personSelected = (Person *) [fetchedResultsController objectAtIndexPath:indexPath];
        [publication removePersonObject:personSelected];

    


我确定我做错了,任何帮助将不胜感激。

想通了。这是我用的

-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath 

    Person *personForCell = (Publisher *) [fetchedResultsController objectAtIndexPath:indexPath];
    cell.textLabel.text = [NSString stringWithFormat:@"%@ %@", personForCell.firstName, personForCell.lastName];

    NSMutableArray *issuesForPersonArray = [[personForCell.publication allObjects] mutableCopy];

    if ([issuesForPersonArray count] != 0) 

        for (Publication *publicationForPerson in issuesForPersonArray) 
            if (publicationForPerson == publication) 
                cell.accessoryType = UITableViewCellAccessoryCheckmark;
            else 
                cell.accessoryType = UITableViewCellAccessoryNone;
            
        
    

【问题讨论】:

【参考方案1】:

您的代码中存在根本的设计缺陷。您正在使用 UI 元素(复选标记)来通知您的数据模型。这很容易出错,并且违反了 MVC(模型-视图-控制器)编程范式的所有规则。

您显示复选标记的基本方法是可以的。参考数据模型来决定使用哪个 UI 元素。但是,这不是使用索引遍历对象的最佳方式。此外,滚动表格视图时循环非常昂贵。这是另一种方法:

(我假设 km 是对相关发布实体实例的引用。)

NSPredicate *predicate = [NSPredicate predicateWithFormat:
   @"ANY issues == %@", km];
NSArray *filteredArray = [[personForCell allObjects] 
   filteredArrayUsingPredicate:predicate];
if (filteredArray.count > 0) // check
else // uncheck

严格来说仍然存在迭代,但框架正在为您完成,因此您不必处理那些越界错误。

当你想改变关系时,你应该使用类似的方法来检索这个信息:

if (filteredArray.count > 0) [personSelected removeIssuesObject:km];
else [personSelected addIssuesObject:km];
[self.tableView reloadData];

【讨论】:

感谢您的回复。我肯定会更改 didSelectRowAtIndexPath。我也会用谓词来回答你的问题。 所以当我尝试谓词时,我得到的是:'NSInvalidArgumentException',原因:'ALL 或 ANY 运算符的左侧必须是 NSArray 或 NSSet。' ' NSPredicate *predicate = [NSPredicate predicateWithFormat: @"ANY issue == %@", publication]; NSArray *filteredArray = [[personForCell.pubs allObjects] filteredArrayUsingPredicate:predicate]; if (filteredArray.count > 0) // 检查 cell.accessoryType = UITableViewCellAccessoryCheckmark; else // 取消选中 cell.accessoryType = UITableViewCellAccessoryNone; ' issueissues ?在我看来,issues 确实是一个 NSSet(即关系中包含的属性)。

以上是关于遍历 iOS Core Data 关系的主要内容,如果未能解决你的问题,请参考以下文章

IOS/Core-Data:添加多对多关系

iOS 5/Lion Core Data 有序关系:指定顺序?

iOS Core Data NSFetchRequest groupby 关系对象

iOS 使用关系检索和排序 Core Data 实体

iOS Core Data 对多关系插入/获取

iOS Core Data:为 Rails 多态关联设置关系的方法