2015-11-12 1 views
0

Я новичок в CoreData и с помощью MagicalRecord, чтобы управлять им. Моя проблема в том, что у меня есть UITableView с NSArray как dataSource, заполненный объектами, которые извлекаются из CoreData db, и все кажется прекрасным, пока я не прокручу таблицу несколько раз.UITableView dataSource объекты становятся нулевыми при прокрутке

Вот мой код:

метод для извлечения данных (MyDatabase.m):

+(NSArray *)getEntities{ 
    ... 

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

Вот как я принести и установить данные UITableView в моем ViewController:

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    myEntitiesArray = [MyDatabase getEntities]; 

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

Адрес setTableData Метод im зация в MyTableView.m:

- (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 печатает сообщения «имя (null)». Я знаю, что этот вопрос, возможно, решался многими людьми и много раз, прежде чем я столкнулся с этой проблемой. Надеюсь, что кто-то поможет мне решить это тоже :)

UPDATE: 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

где ваш метод cellForRowAtIndexPath?Я думаю, что вы используете willDisplayCell, когда вам нужно использовать cellForRowAtIndexPath –

+0

@CCastro см. Мое обновление, я переместил строку с 'willDisplayCell' в' cellForRowAtIndexPath' и не повезло – vendettacore

+0

Измените эту ячейку = [tableView dequeueReusableCellWithIdentifier: cellIdentifier forIndexPath: indexPath]; для этой ячейки = [tableView dequeueReusableCellWithIdentifier: cellIdentifier]; –

ответ

0

Вы должны инициализировать ячейку, вызвав init. Вместо этого, вы делаете следующее:

если (клетка) { [само registerNib: [UINib nibWithNibName: @ "SSCell" пачке: ноль] forCellReuseIdentifier: cellIdentifier]; cell = [tableView dequeueReusableCellWithIdentifier: cellIdentifier forIndexPath: indexPath]; [cell setSelectedBackgroundView: selectedBackgroundView];

Второй звонок пытается повторно использовать существующую ячейку, когда ее нет. Вероятно, это снова вернет нуль.

Будьте очень осторожны с «функцией» объектива C, где вызов метода объекта nil ничего не делает. Вместо того, чтобы сбой с null.pointer.exception как Java, он, вероятно, плавает над [cell SetSelectedBackgroundView: selectedBackgroundView] и целым рядом других строк без проблем.

+0

Я знаю, что 'UITableView' не создает' UITableViewCell' для каждой строки из-за повторного использования. Я создаю свои ячейки и повторно их использую в 'cellForRowAtIndexPath', никаких проблем с самими ящиками не возникает. Проблема с объектами внутри моего массива. Постскриптум попытался переместить строку в 'cellForRowAtIndexPath', не повезло :( – vendettacore

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; 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^