滚动时,UITableView dataSource对象变为null

时间:2015-11-12 19:41:55

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

我是CoreData中的新用户,并使用MagicalRecord来统治它。我的问题是我有UITableView NSArray作为dataSource填充了从CoreData db获取的对象,一切似乎都很好,直到我滚动表一段时间。

这是我的代码:

获取数据的方法(MyDatabase.m):

+(NSArray *)getEntities{
   ...

return [MyEntity MR_findAllSortedBy:@"name" ascending:YES withPredicate:predicate];
}

以下是我在ViewController中获取和设置数据UITableView的方法:

- (void)viewDidLoad {
   [super viewDidLoad];

   myEntitiesArray = [MyDatabase getEntities];

   if(myEntitiesArray.count != 0)
      [myTableView setTableData:myEntitiesArray];
}

以下是MyTableView.m中的setTableData方法实现:

- (void)setTableData:(NSArray *)array {
   if (array && [array count] > 0) {
      _tableData = array;
      [self reloadData];
   }
}

以下是我在MyTableView.m中设置单元格的方法:

- (void)tableView:(UITableView *)tableView willDisplayCell:(SSCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {

   cell.nameLabel.text = [(MyEntity *)_tableData[indexPath.row] name];

}

我尝试将NSLog(@"name is %@",[(MyEntity *)_tableData[indexPath.row] name])放入willDisplayCell,并发现当单元格变空时,NSLog会打印出消息" name is(null)"。我知道在我遇到这个问题之前,很多人可能会解决这个问题。希望有人也会帮助我解决它:)

更新:cellForRowAtIndexPath方法:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  static NSString *cellIdentifier = @"ssCell";
  SSCell *cell = (SSCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
  if( !cell ) {
      [self registerNib:[UINib nibWithNibName:@"SSCell" bundle:nil] forCellReuseIdentifier:cellIdentifier];
      cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
      [cell setSelectedBackgroundView:selectedBackgroundView];
}
  cell.nameLabel.text = [(MyEntity *)_tableData[indexPath.row] name];
  return cell;
}

我也在MyTableView.m init方法中调用此方法:

[self registerNib:[UINib nibWithNibName:@"SSCell" bundle:nil] forCellReuseIdentifier:@"ssCell"];

2 个答案:

答案 0 :(得分:0)

您应该通过调用init来初始化单元格。相反,你正在做以下事情:

  

if(!cell){         [self registerNib:[UINib nibWithNibName:@" SSCell" bundle:nil] forCellReuseIdentifier:cellIdentifier];         cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];         [cell setSelectedBackgroundView:selectedBackgroundView];

当没有可用的单元时,第二次调用会尝试再次重用现有单元。那可能会再次失败。

要非常小心"功能"目标C,其中调用nil对象的方法什么都不做。它不是像Java一样崩溃null.pointer.exception,它可能会漂浮在[cell setSelectedBackgroundView:selectedBackgroundView]和一大堆其他行上而没有问题。

答案 1 :(得分:0)

您必须使用cellForRowAtIndexPath。在这种方法中,细胞被分配。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    /*
     *   This is an important bit, it asks the table view if it has any available cells
     *   already created which it is not using (if they are offscreen), so that it can
     *   reuse them (saving the time of alloc/init/load from xib a new cell ).
     *   The identifier is there to differentiate between different types of cells
     *   (you can display different types of cells in the same table view)
     */

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"];

    /*
     *   If the cell is nil it means no cell was available for reuse and that we should
     *   create a new one.
     */

    if (cell == nil) {

        /* 
        *   Actually create a new cell (with an identifier so that it can be dequeued). 
        */

            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MyIdentifier"];
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
     }

    /*
     *   Now that we have a cell we can configure it to display the data corresponding to
     *   this row/section
     */

      cell.nameLabel.text = [(MyEntity *)_tableData[indexPath.row] name];
    return cell;
 }