我有以下代码尝试让UITableView
的一部分链接到核心数据模型,另一部分是一个带文本的简单单元格:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == 1) {
id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
return [sectionInfo numberOfObjects];
} else {
return 1;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
SubjectCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[SubjectCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (indexPath.section == 0) {
cell.subject.text = @"Favourites";
} else {
Subject *subject = (Subject *)[self.fetchedResultsController objectAtIndexPath:indexPath];
cell.subject.text = subject.subject;
cell.subjectColour.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@", subject.colour]];
}
return cell;
}
然而,应用程序崩溃了,我得到了一个日志输出:
由于未捕获的异常'NSRangeException'而终止应用程序,原因:' * - [__ NSArrayM objectAtIndex:]:索引1超出边界[0 .. 0]
我做错了什么想法?提前谢谢。
答案 0 :(得分:1)
如果您在核心数据中有1个部分,则不得要求第1部分(即第2部分)
tableView:numberOfRowsInSection:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == 1) {
// wrong:
// id <NSFetchedResultsSectionInfo> sectionInfo =
// [self.fetchedResultsController sections][section];
// ^^^^^^^ will be 1
// correct:
if ([[self.fetchedResultsController sections] count] > 0) {
id <NSFetchedResultsSectionInfo> sectionInfo =
[self.fetchedResultsController sections][0];
return [sectionInfo numberOfObjects];
}
else {
// core data is empty
return 0;
}
} else {
// section 0
return 1;
}
}
你应该检查你的NSFetchedResultsController中是否有一个部分。如果核心数据中没有对象,[0]
也会导致出界异常。
由于您的核心数据结果位于第二部分,因此如果您没有任何对象,则可以在numberOfSectionsInTableView:
中返回1。然后您不必检查t:numberOfRowsInSection:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if ([[self.fetchedResultsController sections] count] > 0) {
return 2;
}
else {
// no objects in core data. only show first section
return 1;
}
}
当然,当您从NSFetchedResultsController请求内容时,您必须更改所有indexPath。控制器在第1节中没有任何对象!
// wrong:
// Subject *subject = (Subject *)[self.fetchedResultsController objectAtIndexPath:indexPath];
// correct:
Subject *subject = (Subject *)[self.fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForItem:indexPath.row inSection:0]];
答案 1 :(得分:0)
你的阵列越界了,请使用下面的代码
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == 1) {
return [self.fetchedResultsController count];
} else {
return 1;
}
}
答案 2 :(得分:0)
这是正常的,如果您使用NSFetchedResultsController而未指定sectionKeyName,则返回一个索引等于0的部分。
在您的样本中,您认为:
部分索引0是您的收藏夹
if (indexPath.section == 0) {
cell.subject.text = @"Favourites";
}
和节索引1是您的NSFecthedResultsController结果
else {
Subject *subject = (Subject *)[self.fetchedResultsController objectAtIndexPath:indexPath];
cell.subject.text = subject.subject;
cell.subjectColour.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@", subject.colour]];
}
但是你必须重新创建IndexPath以使用section index to 0
来访问它试试这个:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == 1) {
id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][0];
return [sectionInfo numberOfObjects];
} else {
return 1;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
....
else {
Subject *subject = (Subject *)[self.fetchedResultsController objectAtIndexPath: [NSIndexPath indexPathForItem:indexPath.row inSection:0]
];
cell.subject.text = subject.subject;
cell.subjectColour.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@", subject.colour]];
}
对于didSelectRowAtIndexPath,您使用相同的模式:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 1) {
Subject *subject = (Subject *)[self.fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForItem:indexPath.row inSection:0]];
[self showList:subject animated:YES];
}