两个不同的UIViewControllers中带有NSPredicate的NSFetchedResultsController - NSRangeException

时间:2012-08-09 06:11:41

标签: ios core-data uiviewcontroller nspredicate nsfetchedresultscontroller

我有两个不同的视图,由两个不同的视图控制器控制。每个视图里面都有一个UITableView。每个UITableView都挂钩到NSFetchedResultsController。在视图1中,我不想缩小我的FRC结果,所以我不使用谓词。在View 2中,我使用谓词来获取基于BOOL(aka NSNumber!)值的某些对象。但是当我尝试使用这个谓词时,当我转向View 2时,我得到一个NSRangeException(超出边界的索引1)。当我切换谓词时,它也会抛出异常(谓词1上的谓词,View 2上没有谓词)。再次出现异常,当我转向View 2.有些情况下它是成功的(两者都不是我想要的):

1)我没有对任何一个获取请求使用任何谓词。

2)我对View 1和View 2的获取请求使用相同的谓词。

一些代码供您享受:

在View1.m中:

-(NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
    return _fetchedResultsController;
}
NSManagedObjectContext *context = [CoreDataHelper getContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
                               entityForName:@"EditableSong" inManagedObjectContext:context];
[fetchRequest setEntity:entity];

NSSortDescriptor *sort = [[NSSortDescriptor alloc]
                          initWithKey:@"dateModified" ascending:NO];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
[fetchRequest setFetchBatchSize:5];
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                    managedObjectContext:context sectionNameKeyPath:nil
                                               cacheName:@"Root"];
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;

return _fetchedResultsController;

}

在View2.m

-(NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
    return _fetchedResultsController;
}
NSManagedObjectContext *context = [CoreDataHelper getContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
                               entityForName:@"EditableSong" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc]
                          initWithKey:@"dateModified" ascending:NO];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
NSPredicate *myPredicate = [NSPredicate predicateWithFormat:@"collaborative == %@", [NSNumber numberWithInt:0]];
[fetchRequest setPredicate:myPredicate];
[fetchRequest setFetchBatchSize:5];

NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                    managedObjectContext:context sectionNameKeyPath:nil
                                               cacheName:@"Root"];
NSLog(@"here");
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;

}

这是绿色错误箭头(SIGABRT)指向的位置(顺便说一下,此代码在View1和View2中相同):

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *MyIdentifier = [NSString stringWithFormat:@"MyIdentifier %i", indexPath.row];
SongTableViewCell *cell = (SongTableViewCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
    EditableSong *song = [_fetchedResultsController objectAtIndexPath:indexPath];//<<<------HERE!!! SIGABRT
    song.audioPlayer = [[AudioPlayer alloc] initWithSong:song];
    cell = [[SongTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier editableSong:song andVC:self];
    UIButton *playButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [playButton setBackgroundColor:[UIColor clearColor]];
    [playButton setImage:[UIImage imageNamed:@"mainmenuplay.png"] forState:UIControlStateNormal];
    playButton.frame = CGRectMake(300.0f, 15.0f, 65.0f, 65.0f);
    [playButton addTarget:self action:@selector(playSong:) forControlEvents:UIControlEventTouchUpInside];
    [cell.contentView addSubview:playButton];
}
return cell;

}

谢谢!

更新1

这是我的numberOfRowsInSection方法(同样,两个类都相同):

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
id  sectionInfo =
[[_fetchedResultsController sections] objectAtIndex:section];
NSLog(@"%i", [sectionInfo numberOfObjects]);
return [sectionInfo numberOfObjects];

}

作为参考,该日志应该在View1中打印3,在View2中打印1,但它在两者中打印3。

2 个答案:

答案 0 :(得分:0)

您似乎正在返回错误数量的单元格。 cellForRowAtIndexPath:想要创建一个单元格,但没有objectAtIndexPath

因此,您需要检查numberOfRowsInSection方法。

答案 1 :(得分:0)