【问题标题】:NSFetchRequest for sub objects in rowsNSFetchRequest 用于行中的子对象
【发布时间】:2014-04-27 04:46:40
【问题描述】:

我的数据模型如下: 类别

—>名字

—>items(“汽车”类型的项目数组)

我正在尝试使用部分作为名称来获取,并且行应该是项目(这是一个 NSArray)

这是我的代码,我希望将行作为 Car 返回,但它仍然返回“Category”。那么,什么是 NSFetchRequest?

NSFetchRequest *request=[[NSFetchRequest alloc] initWithEntityName:@"Categories"];


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

fetchController=[[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:delegate.managedContext sectionNameKeyPath:@"name" cacheName:nil];
NSError *fetchError;
[fetchController performFetch:&fetchError];

我已附上模型的图片。

取车代码如下。

AppDelegate *del=(AppDelegate*)[UIApplication sharedApplication].delegate;
NSFetchRequest *request=[[NSFetchRequest alloc] initWithEntityName:@"Car"];


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

fetchController=[[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:del.managedContext sectionNameKeyPath:@"Categories.name" cacheName:nil];
NSError *fetchError;
[fetchController performFetch:&fetchError];

代码在这里上传https://www.dropbox.com/s/jjk0nve3pmytui2/TestAppData%202.zip

注意:- 我正在考虑显示空白部分,因为我可以查看具有“添加”按钮的标题。所以,通过这个用户可以很容易地知道类别的数量。

为了实现上面“注意”中提到的事情,我尝试了以下方法。我创建了一个CarViewController2。它创建了相同数量的类别,但行数取决于categoriesRelationship(这是一个NSOrderedSet)。可以通过取消注释 ViewController.m 的 (IBAction) addCategory:(id) sender 中的一些代码来测试这一点。 (取消评论一次,之后再评论)代码已经更新,可以下载了。

如果需要,请更正代码。谢谢。

【问题讨论】:

    标签: ios core-data nsfetchedresultscontroller nsfetchrequest


    【解决方案1】:

    您的设置应该是:

    NSFetchRequest *request=[[NSFetchRequest alloc] initWithEntityName:@"Car"];
    NSSortDescriptor *sortDesc=[[NSSortDescriptor alloc] initWithKey:@"category.name" ascending:YES];
    [request setSortDescriptors:[NSArray arrayWithObject:sortDesc]];
    
    fetchController=[[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                        managedObjectContext:delegate.managedContext 
                                                          sectionNameKeyPath:@"category.name" 
                                                                   cacheName:nil];
    

    category.name 假设 Category items 的反向关系是 Car category(一对多关系)

    请注意,您可能希望将排序描述符更改为按某些 Car 属性排序

    编辑:

    发布模型和当前代码后,您不能按 Category 名称对数据进行分段,因为这是多对多关系。
    不同部分不能有重复项。

    如果Car 'c' 属于类别 'g1' 和 'g2' 你要么需要自己构建数据结构,要么引入一个连接汽车和类别的中间实体,这将是请求将立足。

    编辑 2:

    在您的项目中,您将carRelation 设置为Categories 实体,这将允许您形成以下请求:

    NSFetchRequest *request=[[NSFetchRequest alloc] initWithEntityName:@"Car"];
    NSSortDescriptor *sortDesc=[[NSSortDescriptor alloc] initWithKey:@"carName" ascending:YES];
    [request setSortDescriptors:[NSArray arrayWithObject:sortDesc]];
    
    fetchController=[[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                        managedObjectContext:delegate.managedContext 
                                                          sectionNameKeyPath:@"carRelation.categoryName" 
                                                                   cacheName:nil];
    

    这仍然不会显示其中没有汽车的类别(因为它应该有汽车视图和类别视图)。

    编辑 3:

    您对CarViewController.m的代码更正:

    -(void) getData{
        AppDelegate *del=(AppDelegate*)[UIApplication sharedApplication].delegate;
        NSFetchRequest *req=[[NSFetchRequest alloc] initWithEntityName:@"Car"];
        NSSortDescriptor *descriptor1=[[NSSortDescriptor alloc] initWithKey:@"carRelationship.categoryName" ascending:YES];
        NSSortDescriptor *descriptor2=[[NSSortDescriptor alloc] initWithKey:@"carName" ascending:YES];
        [req setSortDescriptors:@[descriptor1,descriptor2]];
        fetchController=[[NSFetchedResultsController alloc] initWithFetchRequest:req managedObjectContext:del.managedContext sectionNameKeyPath:@"carRelationship.categoryName" cacheName:nil];
        NSError *fetchError;
        fetchController.delegate=self;
        [fetchController performFetch:&fetchError];
        NSLog(@"Fetch ERROR= %@",fetchError);
    }
    
    - (NSString*) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
    {
        id<NSFetchedResultsSectionInfo> sectionInfo=[[fetchController sections] objectAtIndex:section];
        return [sectionInfo name];
    }
    

    正如我之前解释的,这仍然不会显示其中没有汽车的类别

    【讨论】:

    • 我确实添加了关系,但它没有更新核心数据模型类,所以我必须删除并重新创建该类。如果“汽车”实体为空,它会显示一个部分列表。由于实体“类别”中仍然存在类别(例如 SUV 和跑车等)。可以举个例子吗?
    • @andyPaul 这不会导致空白部分(其中没有汽车的类别)。重新生成具有关系的类(尽管将其添加到实体中就足够了),并在添加 Car 对象时设置它。你想要什么类型的例子?
    • 我已经编辑了代码,如果我需要指定其他内容来解决它,请告诉我。
    • @andyPaul 您应该按carName 属性排序,这是在您的Car 实体中定义的属性。
    • 抓取时崩溃。
    【解决方案2】:

    我们试试

    NSFetchRequest *request=[[NSFetchRequest alloc] initWithEntityName:@"Category"];
    NSSortDescriptor *sortDesc=[[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
    [request setSortDescriptors:[NSArray arrayWithObject:sortDesc]];
    fetchController=[[NSFetchedResultsController alloc] initWithFetchRequest:request   managedObjectContext:delegate.managedContext sectionNameKeyPath:@"name" cacheName:nil];
    NSError *fetchError;
    [fetchController performFetch:&fetchError];
    
    NSArray *categories = [fetchedResultsController fetchedObjects];
    for(Category *c in categories){
       NSSet *items = c.items;// array that you want
    }
    

    【讨论】:

    • performFetch 填充数组,节数和行数由 fetchController 设置。您提供的解决方案不适用于我现有的代码。
    • @andyPaul:performFetch 返回 BOOL 而不是数组。 NSArray *categories = [fetchedResultsController fetchedObjects] -> 你得到什么类别?什么数组?
    猜你喜欢
    • 1970-01-01
    • 2014-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多