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