获取核心数据中具有关系的实体

发布于 2024-11-19 13:18:04 字数 5742 浏览 7 评论 0原文

我的核心数据数据库中有 2 个实体 PersonPhoto,其中 PersonTo-Many 关系 < code>Photo 和 PhotoPerson (Person<-->>Photo) 具有相反的关系。我通过以下方式从 .plist 加载我的应用程序的一些初始数据:

-(void)populateDataStorage{

    NSString *path = [[NSBundle mainBundle] pathForResource:@"FakeData" ofType:@"plist"];

    if(path){
        NSArray *plistData = [[NSArray alloc] initWithContentsOfFile:path];
        NSEnumerator *enumerator = [plistData objectEnumerator];

        NSArray *personResults;

        Photo *photo;
        Person *person;

        id currItem = [enumerator nextObject];

        while (currItem != nil) {
            photo = (Photo *)[NSEntityDescription insertNewObjectForEntityForName:@"Photo" inManagedObjectContext:[flickrFetcher managedObjectContext]];

            photo.name = [currItem objectForKey:@"name"];
            photo.path = [currItem objectForKey:@"path"];

            NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@", [currItem objectForKey:@"user"]];

            personResults = [flickrFetcher fetchManagedObjectsForEntity:@"Person" withPredicate:predicate];

            if ([personResults count] > 0) {
                person = [personResults objectAtIndex:0];
            } 
            else {
                person = (Person *)[NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:[flickrFetcher managedObjectContext]];
                person.name = [currItem objectForKey:@"user"];
            }

            photo.person = person;
            [person addPhotosObject:photo];

            NSLog(@"Photo %@ added for user %@", photo.name, person.name);

            currItem = [enumerator nextObject];
        }

        [plistData release];

    }

}

一切都正确加载。然后,我使用 NSFetchedResultsController 获取 Person 并加载 UITableView,一切正常。当用户单击属于用户的单元格时,我必须加载另一个包含所选人员照片的 UITableView ,因此我在 UITableViewController 中为我的照片的表格视图执行以下操作

 - (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"person = %@", person];
        self.fetchedResultsController = [[FlickrFetcher sharedInstance] fetchedResultsControllerForEntity:@"Photo" withPredicate:predicate];
    }
    return self;
}

: >viewDidLoad :

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSError *error = nil;
    [fetchedResultsController performFetch:&error];

    for(Photo *photo in person.photos){
        NSLog(@"Photo %@ belongs to %@", photo.name, person.name);
    }

    NSLog(@"Photo count %d", [[fetchedResultsController fetchedObjects] count]);
}

计数给了我 0,我从来没有得到该人的照片,但我知道它们已正确保存,因为它们都为传入的 Person 打印出来。知道我可能做错了什么吗?

编辑

用于在我的 FlickrFetcher 类中获取 NSFetchedResultsController 的实用方法:

- (NSFetchedResultsController *)fetchedResultsControllerForEntity:(NSString*)entityName withPredicate:(NSPredicate*)predicate {
    NSFetchedResultsController *fetchedResultsController;

    /*
     Set up the fetched results controller.
     */
    // Create the fetch request for the entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:[self managedObjectContext]];
    [fetchRequest setEntity:entity];

    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];

    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

    [fetchRequest setSortDescriptors:sortDescriptors];

    // Add a predicate if we're filtering by user name
    if (predicate) {
        [fetchRequest setPredicate:predicate];
    }

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[self managedObjectContext] sectionNameKeyPath:nil cacheName:@"Root"];

    [fetchRequest release];
    [sortDescriptor release];
    [sortDescriptors release];

    return [fetchedResultsController autorelease];
}

我自己的 NSFetchedResultsController 在我的 UITableViewController 中创建:

NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Photo" inManagedObjectContext:[flickFetcher managedObjectContext]];

    [request setEntity:entity];

    NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:descriptor, nil];

    [request setSortDescriptors:sortDescriptors];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"person = %@", person];

    [request setPredicate:predicate];

    fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:[flickFetcher managedObjectContext] sectionNameKeyPath:nil cacheName:@"Root"];

    [request release];
    [descriptor release];
    [sortDescriptors release];

    NSError *error = nil;
    [fetchedResultsController autorelease];
    [fetchedResultsController performFetch:&error];

我不看不出有什么区别。

I have 2 entities in my Core Data database Person and Photo a Person has a To-Many relationship with Photo and Photo has a reverse relationship with Person (Person<-->>Photo). I load some initial data for my app off a .plist in the following manner:

-(void)populateDataStorage{

    NSString *path = [[NSBundle mainBundle] pathForResource:@"FakeData" ofType:@"plist"];

    if(path){
        NSArray *plistData = [[NSArray alloc] initWithContentsOfFile:path];
        NSEnumerator *enumerator = [plistData objectEnumerator];

        NSArray *personResults;

        Photo *photo;
        Person *person;

        id currItem = [enumerator nextObject];

        while (currItem != nil) {
            photo = (Photo *)[NSEntityDescription insertNewObjectForEntityForName:@"Photo" inManagedObjectContext:[flickrFetcher managedObjectContext]];

            photo.name = [currItem objectForKey:@"name"];
            photo.path = [currItem objectForKey:@"path"];

            NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@", [currItem objectForKey:@"user"]];

            personResults = [flickrFetcher fetchManagedObjectsForEntity:@"Person" withPredicate:predicate];

            if ([personResults count] > 0) {
                person = [personResults objectAtIndex:0];
            } 
            else {
                person = (Person *)[NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:[flickrFetcher managedObjectContext]];
                person.name = [currItem objectForKey:@"user"];
            }

            photo.person = person;
            [person addPhotosObject:photo];

            NSLog(@"Photo %@ added for user %@", photo.name, person.name);

            currItem = [enumerator nextObject];
        }

        [plistData release];

    }

}

Everything loads properly. Then I use a NSFetchedResultsController to get the Person and load a UITableView and it all works. When the user clicks on a cell that belongs to a user I have to load another UITableView with the selected Person's Photos, so I do the following in my UITableViewController for my Photo's table view:

 - (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"person = %@", person];
        self.fetchedResultsController = [[FlickrFetcher sharedInstance] fetchedResultsControllerForEntity:@"Photo" withPredicate:predicate];
    }
    return self;
}

And in my viewDidLoad :

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSError *error = nil;
    [fetchedResultsController performFetch:&error];

    for(Photo *photo in person.photos){
        NSLog(@"Photo %@ belongs to %@", photo.name, person.name);
    }

    NSLog(@"Photo count %d", [[fetchedResultsController fetchedObjects] count]);
}

The count is giving me 0, i never get the Person's Photos but I know they are properly saved because they all print out for the passed in Person. Any idea what I might be doing wrong?

EDIT

Utility method for getting the NSFetchedResultsController in my FlickrFetcher class:

- (NSFetchedResultsController *)fetchedResultsControllerForEntity:(NSString*)entityName withPredicate:(NSPredicate*)predicate {
    NSFetchedResultsController *fetchedResultsController;

    /*
     Set up the fetched results controller.
     */
    // Create the fetch request for the entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:[self managedObjectContext]];
    [fetchRequest setEntity:entity];

    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];

    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

    [fetchRequest setSortDescriptors:sortDescriptors];

    // Add a predicate if we're filtering by user name
    if (predicate) {
        [fetchRequest setPredicate:predicate];
    }

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[self managedObjectContext] sectionNameKeyPath:nil cacheName:@"Root"];

    [fetchRequest release];
    [sortDescriptor release];
    [sortDescriptors release];

    return [fetchedResultsController autorelease];
}

My own NSFetchedResultsController created in my UITableViewController:

NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Photo" inManagedObjectContext:[flickFetcher managedObjectContext]];

    [request setEntity:entity];

    NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:descriptor, nil];

    [request setSortDescriptors:sortDescriptors];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"person = %@", person];

    [request setPredicate:predicate];

    fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:[flickFetcher managedObjectContext] sectionNameKeyPath:nil cacheName:@"Root"];

    [request release];
    [descriptor release];
    [sortDescriptors release];

    NSError *error = nil;
    [fetchedResultsController autorelease];
    [fetchedResultsController performFetch:&error];

I don't see the difference.

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

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

发布评论

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

评论(1

无畏 2024-11-26 13:18:04

不要立即看到任何东西。在插入所有测试数据后,我想在上下文中插入保存。 (并且下次不再插入它。)

一个评论:

photo.person = person;
[person addPhotosObject:photo];

这是多余的。如果您设置另一个关系,则在核心数据中使用反向关系建模的关系将正确设置反向关系。因此,只需要其中一根线。

Don't see anything offhand. I'd want to insert a save on the context after I inserted all the test data. (And not insert it next time around.)

One comment:

photo.person = person;
[person addPhotosObject:photo];

this is redundant. A relationship that is modeled with a reverse relationship in core data will correctly set the reverse relationship, if you set the other. So, only one of these lines is needed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文