首页 文章

核心数据:获取特定对象的多对多关系中的所有实体?

提问于
浏览
4

在我的iPhone应用程序中,我使用简单的核心数据模型和两个实体( ItemProperty ):

Item
名称
性能

Property
名称

项目

Item 有一个属性(名称)和一个一对多关系(属性) . 它的反比关系是项目 . Property 有两个属性相反的反向关系 .

现在我想在两个级别的表视图中显示我的数据 . 第一个列出所有项目;当选择一行时,新的UITableViewController被推送到我的UINavigationController的堆栈中 . 新的UITableView应该显示所选项目的所有属性(即它们的名称) .

为此,我使用存储在实例变量中的 NSFetchedResultsController . 在第一级,在设置NSFetchedResultsController时一切正常,如下所示:

-(NSFetchedResultsController *) fetchedResultsController {
    if (fetchedResultsController) return fetchedResultsController;

    // goal: tell the FRC to fetch all item objects.
    NSFetchRequest *fetch = [[NSFetchRequest alloc] init];

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:self.moContext];
    [fetch setEntity:entity];

    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
    [fetch setSortDescriptors:[NSArray arrayWithObject:sort]];

    [fetch setFetchBatchSize:10];

    NSFetchedResultsController *frController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetch managedObjectContext:self.moContext sectionNameKeyPath:nil cacheName:@"cache"];
    self.fetchedResultsController = frController;
    fetchedResultsController.delegate = self;

    [sort release];
    [frController release];
    [fetch release];

    return fetchedResultsController;
}

但是,在二级UITableView上,我似乎做错了什么 . 我以类似的方式实现了fetchedresultsController:

-(NSFetchedResultsController *) fetchedResultsController {
    if (fetchedResultsController) return fetchedResultsController;

    // goal: tell the FRC to fetch all property objects that belong to the previously selected item
    NSFetchRequest *fetch = [[NSFetchRequest alloc] init];

    // fetch all Property entities.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Property" inManagedObjectContext:self.moContext];
    [fetch setEntity:entity];

    // limit to those entities that belong to the particular item
    NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"item.name like '%@'",self.item.name]];
    [fetch setPredicate:predicate];

    // sort it. Boring.
    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
    [fetch setSortDescriptors:[NSArray arrayWithObject:sort]];

    NSError *error = nil;
    NSLog(@"%d entities found.",[self.moContext countForFetchRequest:fetch error:&error]);
    // logs "3 entities found."; I added those properties before. See below for my saving "problem".
    if (error) NSLog("%@",error);
    // no error, thus nothing logged.

    [fetch setFetchBatchSize:20];

    NSFetchedResultsController *frController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetch managedObjectContext:self.moContext sectionNameKeyPath:nil cacheName:@"cache"];
    self.fetchedResultsController = frController;
    fetchedResultsController.delegate = self;

    [sort release];
    [frController release];
    [fetch release];

    return fetchedResultsController;
}

现在它变得很奇怪了 . 上面的 NSLog 语句返回所选项的正确数量的属性 . 但是,UITableViewDelegate方法告诉我没有属性:

-(NSInteger) tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
    NSLog(@"Found %d properties for item \"%@\". Should have found %d.",[sectionInfo numberOfObjects], self.item.name, [self.item.properties count]);
    // logs "Found 0 properties for item "item". Should have found 3."
    return [sectionInfo numberOfObjects];
}

相同的实现在第一级工作正常 .

它变得更加怪异 . 我实现了某种UI来添加属性 . 我通过 Property *p = [NSEntityDescription insertNewObjectForEntityForName:@"Property" inManagedObjectContext:self.moContext]; 创建一个新的 Property 实例,设置关系并调用 [self.moContext save:&error] . 这似乎有效,因为 error 仍然是 nil 并且对象被保存(我可以在记录 Item 实例时看到属性的数量,见上文) . 但是,不会触发委托方法 . 这似乎是由于可能搞砸了fetchRequest(Controller) .

有任何想法吗?我弄乱了第二次获取请求吗?这是获取特定实例的多对多关系中所有实体的正确方法吗?

1 回答

  • 2

    您需要实际执行表视图控制器的提取:

    // ...create the fetch results controller...    
    NSError *fetchRequestError;
    BOOL success = [fetchedResultsController performFetch:&fetchRequestError];
    

相关问题