ios - 将核心数据对象传递给新的 TableView Controller ,但使用对象的关系在新的 View Controller 中显示该数据

标签 ios objective-c core-data nsfetchedresultscontroller nsfetchrequest

在 TableView Controller 之间传递对象时,我遇到了一个未捕获的异常,即基于核心数据的应用程序在运行时发送了错误的选择器。

我面临的问题(当您阅读这个问题时会变得更加清楚)是我不确定如何引用核心数据对象的关系而不是调用对象本身。

让我们退后一步看看模型,应用程序的前提很简单;允许用户创建包含名称、金额、场合和日期的“交易”。

具有 wasGiven 属性的事务实体 具有 name 属性的 Person 实体 具有标题属性的场合实体 具有 amount 属性的 Item 实体 该事务与 Person 实体 (whoBy) 存在关系、与 Occasion 实体 (occasion) 的链接以及与 Item 实体 (itemType) 的链接。

编辑:核心数据模型

enter image description here

该应用程序是一个简单的 2 个选项卡表格 View Controller - 第一个选项卡包含所有信息,按日期划分。对于这个 TableViewController,我正在使用以下 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;
    NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:@"occasion.dateOfEvent" cacheName:nil];
    self.fetchedResultsController = theFetchedResultsController;
    _fetchedResultsController.delegate = self;
    return _fetchedResultsController;
}

第二个选项卡仅包含“名称”信息。有一个加号按钮,当用户按下该按钮时,他们会看到一个模态视图,可以添加名称、场合、金额和日期。他们按下保存并将其保存到核心数据数据库。因此,第二个选项卡仅显示名称(我必须做很多工作才能使其正常工作,因此不会重复),但第二个 TableView 的 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 将其标题设置为所选名称。

我想要在这个新的 TableView 中显示的是那个人的历史记录 - 与原来的第一个选项卡非常相似,但只是针对这个人量身定制的,这就是我认为我应该使用谓词的原因。

选定的 TableView 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'

我明白为什么会发生这种情况;我正在传递一个事务并显示一个事务,但我无法在人员 TableView 中使用事务,因为它会为该人员创建重复项(这是我在这里遇到的大问题),那么我如何才能以某种方式对此进行种姓?我需要在选定 TableView 中使用事务 fetchRequest 的原因是因为我需要引用日期、标题和金额,所有这些都与事务相关,而不是人员的一部分。

对此的任何帮助将不胜感激!

最佳答案

prepareForSegue:中,获取的结果 Controller 获取Person对象,而不是 事务对象。因此

Transaction *selectedTransaction = [self.fetchedResultsController objectAtIndexPath:indexPath];

实际上是一个Person(将其转换为Transaction不会改变这一事实)。 所以你应该将其更改为

Person *selectedPerson = [self.fetchedResultsController objectAtIndexPath:indexPath];
EnvylopeSelectedPersonTableViewController *selectedPersonVC = [segue destinationViewController];
selectedPersonVC.person = selectedPerson;

其中 person 是 EnvylopeSelectedPersonTableViewController 的属性:

@property (nonatomic, strong) Person *person;

显示此人所有交易的谓词将是

fetchRequest.predicate = [NSPredicate predicateWithFormat:@"whoBy = %@", self.person];

关于ios - 将核心数据对象传递给新的 TableView Controller ,但使用对象的关系在新的 View Controller 中显示该数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20080889/

相关文章:

ios - 需要有关核心数据的帮助

ios - 核心数据、NSNumber、整数 32 和整数 64

iphone - 使用 iPhone 发送 HTML 到远程客户端

ios - 在 Swift 4 中获取 Url 图片的分辨率

ios - 如何根据 UITableView 中的单元格数量更改 UITableViewCell 内 UItableView 的高度

objective-c - 强制 UIWebView 在 MobileSafari 中加载的魔术 URL?

ios - UIViewController 中的 UICollectionView

ios - 如何杀死 Vapor 服务器

objective-c - iOS6 UITableView 部分标题重复

core-data - 在 MonoTouch 中使用 CoreData?