获取与 NSFetchedResultsController 有关系的对象

Posted

技术标签:

【中文标题】获取与 NSFetchedResultsController 有关系的对象【英文标题】:Fetch Object with relationship with NSFetchedResultsController 【发布时间】:2014-03-08 09:41:06 【问题描述】:

这是我的问题:

我有 2 个实体:

Session(日期日期、字符串名称、NSSet 行为)

Behaviour(字符串类别、字符串时间、字符串名称、NSManagedobject 会话)。

它们是一对多的关系。

SessioneViewController 中,我获取SessionBehaviours:

// This is for the fetch request
@property (nonatomic, ratain) NSArray *sessionArray; 

// Here I create the Session Object

Session *newSession = [NSEntityDescription insertNewObjectForEntityForName:@"Session"    inManagedObjectContext:self.managedObjectContext];
newSession.name = self.lblName.text;
newSession.date = [NSDate date];
self.managedObjectContext save:nil];
// I add the Session into the Array
self.sessionsArray = [self.sessionsArray arrayByAddingObject:newSession];

// Here I create the Behaviour Object:
Comportamento *newBehaviour = [NSEntityDescription   insertNewObjectForEntityForName:@"Behaviour" inManagedObjectContext:self.managedObjectContext];     
newBehaviour.name = cell.textLabel.text;
newBehaviour.category = @"Relationship";
newBehaviour.time = _lblTimer.text;

// Here I say which Session is part of the Behaviour
// --- EDIT ---
// Error Code: newBehaviour.session = [self.sessionsArray objectAtIndex:indexPath.row];
newBehaviour.session = [self.sessionsArray lastObject];

然后我有两个视图控制器类,其中我想在其中显示Session s,然后选择Session我想要相关的Behaviour s。

// In "ArchiveSessionVC.h":
@property (nonatomic, strong) NSFetchedResultsController *frs;
// In "ArchiveSessionVC.m":

- (void) viwDidLoad

   if(![[self frs] performFetch:&e]) 
    NSLog(@"Error %@", e);
    abort();



-(NSFetchedResultsController *)frs 
if (_frs != nil) 
    return _frs;

   NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
   NSEntityDescription *entity = [NSEntityDescription entityForName:@"Session" inManagedObjectContext:self.managedObjectContext];
   [fetchRequest setEntity:entity];

   NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date"
                                                               ascending:NO];
   NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
   [fetchRequest setSortDescriptors:sortDescriptors];

   _frs = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];

    return _fetchedResultControllerSessions; 



- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

       static NSString *CellIdentifier = @"SessioneCell";

       UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
       if (cell == nil) 
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault  reuseIdentifier:CellIdentifier];
        

        Sessione *sessione = [self.fetchedResultControllerSessions      objectAtIndexPath:indexPath];
        cell.textLabel.text = sessione.nome;

        return cell;

这里是我推动第二个视图控制器以显示Behaviuors:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

      // Push del ViewController dei comportamenti:

      ArchiveBehaviuorsVC *aBehavioursVC =   [[ArchiveBehaviuorsVC alloc]   initWithNibName:@"ArchiveBehaviuorsVC" bundle:nil];
      aBehavioursVC.sessioneSelezionata = [self.fetchedResultControllerSessions     objectAtIndexPath:indexPath];
      [self.navigationController pushViewController:aBehavioursVC animated:YES];

我的ArchiveBehaviuorsVC是这样的:

 //"ArchiveBehaviuorsVC.h"
 @property (nonatomic, strong) Session *selectedSession;

 -(NSFetchedResultsController *)fetchedResultControllerBehaviours
 
    if (_fetchedResultControllerBehaviours != nil) 
    return _fetchedResultControllerBehaviours;
    

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Behaviour" inManagedObjectContext:self.managedObjectContext];
    //NSPredicate *predicate = [NSPredicate predicateWithFormat:@"session == %@",self.sessioneSelezionata];
    [fetchRequest setEntity:entity];
    [fetchRequest setPredicate:predicate];


    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"nome"
                                                               ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    [fetchRequest setSortDescriptors:sortDescriptors];

    _fetchedResultControllerBehaviours = [[NSFetchedResultsController alloc]   initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext   sectionNameKeyPath:nil cacheName:nil];


    return _fetchedResultControllerBehaviours;
 

这是代码的一部分,但它不起作用。如何告诉fetchedResultzController 仅显示与Session 关联的Behaviours?

-- 编辑 ---

我发现了问题,不是 NSPredicate 错误,问题出在这行代码:

// 错误代码:newBehaviour.session = [self.sessionsArray objectAtIndex:indexPath.row];

// 正确代码:

newBehaviour.session = [self.sessionsArray lastObject];

【问题讨论】:

什么不起作用?取消注释谓词并将 aBehavioursVC 传递给 MOC。 不起作用的部分是 fetchedResultControllerBehaviours,当我选择会话时它没有显示正确的行为。抱歉,我必须在哪里通过“aBehavioursVC”? 那么 FRC 确实提供了一些行为?这些是什么?他们怎么错了。除了注释掉的谓词之外,代码中没有任何明显错误的地方。 【参考方案1】:

谓词

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"session == %@",self.sessioneSelezionata];

在我看来还不错。 你确定你得到了错误的行为吗?你试过enable SQL debugging吗?

-com.apple.CoreData.SQLDebug X

其中 X 可以是 1,2 或 3。值越高,SQL 输出越多。

此外,当您执行save 总是时,请传入错误参考。

NSError* error = nil;
[context save:&error];

上面的 sn-p 返回一个 bool 值,所以检查一下。如果返回NO,则打印错误。

【讨论】:

以上是关于获取与 NSFetchedResultsController 有关系的对象的主要内容,如果未能解决你的问题,请参考以下文章

又一个 NSInternalInconsistencyException,但使用 NSFetchedResultsController

Core Data 中计算的持久属性

更新相关 NSManagedObject 时更新 UITableView

NSFetchedResultsController:具有相同键的两个排序描述符不起作用。一个降序用于部分,另一个升序用于行

Kotlin集合操作 ① ( List 创建与元素获取 | 安全获取集合元素 | getOrElse | getOrNull )

Kotlin集合操作 ① ( List 创建与元素获取 | 安全获取集合元素 | getOrElse | getOrNull )