在运行时发送错误的选择器时,我面临一个未捕获的异常,当在表视图控制器之间传递对象时,基于核心数据的应用程序 .
我所面临的问题(当你阅读这个问题时会变得更清楚)是我不确定如何引用Core Data Objects的关系而不是调用Object本身 .
让我们退一步看看模型,应用程序的前提很简单;允许用户创建具有名称,数量,场合和日期的“交易” .
具有wasGiven属性的Transaction Entity具有name属性的Person Entity具有title属性的Occasion Entity具有amount属性的Item Entity该事务与Person实体(whoBy),到Occasion Entity(场合)的链接以及到Item Entity的链接(物品种类) .
EDIT: Core Data Model
该应用程序是一个简单的2 Tabb-ed表视图控制器 - 第一个选项卡包含所有信息,按日期划分 . 对于这个TableViewController,我正在使用以下fetchedResultsController代码查看“Transaction Entity”:
- (NSFetchedResultsController *)fetchedResultsController
{
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
if (_fetchedResultsController != nil)
{
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Transaction" inManagedObjectContext:managedObjectContext];
fetchRequest.entity = entity;
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"occasion.dateOfEvent" ascending:NO];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:sort];
fetchRequest.fetchBatchSize = 20;
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:@"occasion.dateOfEvent" cacheName:nil];
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
第二个选项卡仅包含“名称”信息 . 有一个加号按钮,当用户按下它时,它们会显示一个模态视图,以添加名称,场合,数量和日期 . 他们按保存并将其保存到核心数据数据库 . 所以第二个选项卡只显示名称(我必须做很多工作才能使这个位工作,所以它不重复)但是第二个表视图的fetchedResultsController是:
- (NSFetchedResultsController *)fetchedResultsController
{
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
if (_fetchedResultsController != nil)
{
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:managedObjectContext];
fetchRequest.entity = entity;
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:sort];
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil];
self.fetchedResultsController = theFetchedResultsController; _fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
当我选择一行时,将调用prepareForSegue方法:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSIndexPath *indexPath = [self.personTableView indexPathForCell:sender];
Transaction *selectedTransaction = [self.fetchedResultsController objectAtIndexPath:indexPath];
if ([segue.identifier isEqualToString:@"Selected Person Segue"])
{
EnvylopeSelectedPersonTableViewController *selectedPerson = [segue destinationViewController];
[selectedPerson setTransaction:selectedTransaction];
}
}
所以在SelectedTableView中,我显然有一个属性来保存:
@property (nonatomic, strong) Transaction *transaction;
使用setter将其 Headers 设置为所选名称 .
我在这个新的Table视图中想要的是显示那个人的历史 - 与原始的第一个标签非常相似,但只是为这个人定制,这就是为什么我认为我会使用谓词 .
选中的表视图fetchedResultsController是:
- (NSFetchedResultsController *)fetchedResultsController
{
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
if (_fetchedResultsController != nil)
{
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Transaction" inManagedObjectContext:managedObjectContext];
fetchRequest.entity = entity;
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"occasion.dateOfEvent" ascending:NO];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:sort];
fetchRequest.fetchBatchSize = 20;
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"whoBy.name = %@", self.transaction.whoBy.name];
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:@"occasion.dateOfEvent" cacheName:nil];
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
这是一个例外:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Person whoBy]: unrecognized selector sent to instance 0x8b550b0'
我明白为什么会这样;我正在传递一个事务并显示一个事务,但是我不能在Person Table View中使用Transaction,因为它会为这个人创建重复项(这是我在这里遇到的大问题),所以我怎么能以某种方式解决这个问题呢?我需要在Selected Table View中使用Transaction fetchRequest的原因是因为我需要引用日期, Headers 和金额,所有这些都与Transaction相关而不是Person的一部分 .
任何有关这方面的帮助都将受到大力赞赏!
1 回答
在
prepareForSegue:
中,获取的结果控制器获取Person对象,而不是Transaction对象 . 因此实际上是
Person
(将其转换为Transaction
并不会改变这一事实) . 所以你应该把它改成其中
person
是EnvylopeSelectedPersonTableViewController的属性:显示该人的所有交易的谓词就是这样