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

发布于 2024-10-09 21:13:32 字数 4377 浏览 0 评论 0原文

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

Item
姓名
属性

属性
姓名

item

Item 具有一个属性(名称)和一个一对多关系(属性)。它的逆关系是item属性有两个按反比关系的属性。

现在我想在两个级别的表视图中显示我的数据。第一个列出了所有项目;当选择一行时,一个新的 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 保存:&错误]。这似乎有效,因为 error 仍然 nil 并且对象被保存(我可以在记录 Item 实例时看到属性的数量,见上文)。但是,委托方法不会被触发。在我看来,这是由于 fetchRequest(Controller) 可能混乱所致。

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

in my iPhone application I am using simple Core Data Model with two entities (Item and Property):

Item
name
properties

Property
name
value
item

Item has one attribute (name) and one one-to-many-relationship (properties). Its inverse relationship is item. Property has two attributes the according inverse relationship.

Now I want to show my data in table views on two levels. The first one lists all items; when one row is selected, a new UITableViewController is pushed onto my UINavigationController's stack. The new UITableView is supposed to show all properties (i.e. their names) of the selected item.

To achieve this, I use a NSFetchedResultsController stored in an instance variable. On the first level, everything works fine when setting up the NSFetchedResultsController like this:

-(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;
}

However, on the second-level UITableView, I seem to do something wrong. I implemented the fetchedresultsController in a similar way:

-(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;
}

Now it's getting weird. The above NSLog statement returns me the correct number of properties for the selected item. However, the UITableViewDelegate method tells me that there are no properties:

-(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];
}

The same implementation works fine on the first level.

It's getting even weirder. I implemented some kind of UI to add properties. I create a new Property instance via Property *p = [NSEntityDescription insertNewObjectForEntityForName:@"Property" inManagedObjectContext:self.moContext];, set up the relationships and call [self.moContext save:&error]. This seems to work, as error is still nil and the object gets saved (I can see the number of properties when logging the Item instance, see above). However, the delegate methods are not fired. This seems to me due to the possibly messed up fetchRequest(Controller).

Any ideas? Did I mess up the second fetch request? Is this the right way to fetch all entities in a to-many-relationship for a particular instance at all?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

诗酒趁年少 2024-10-16 21:13:32

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

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

You need to actually perform the fetch for the table view controller:

// ...create the fetch results controller...    
NSError *fetchRequestError;
BOOL success = [fetchedResultsController performFetch:&fetchRequestError];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文