NSFetchRequest 用于行中的子对象
Posted
技术标签:
【中文标题】NSFetchRequest 用于行中的子对象【英文标题】:NSFetchRequest for sub objects in rows 【发布时间】: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 中的一些代码来测试这一点。 (取消评论一次,之后再评论)代码已经更新,可以下载了。
如果需要,请更正代码。谢谢。
【问题讨论】:
【参考方案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] -> 你得到什么类别?什么数组?以上是关于NSFetchRequest 用于行中的子对象的主要内容,如果未能解决你的问题,请参考以下文章
NSFetchRequest 在第一次运行时返回对象,但以后不返回
NSFetchRequest 带有用于递归 CoreData 实体关系的排序描述符
使用javascript替换textarea中所有行中的子字符串
用于 groupby 和 count 组合的 NSFetchRequest