一部分是Core Data,另一部分是UITableView中的NSMutableArray

时间:2013-10-22 13:30:52

标签: ios objective-c uitableview core-data nsfetchedresultscontroller

我有以下代码尝试让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]

我做错了什么想法?提前谢谢。

3 个答案:

答案 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];
}