Продолжаете получать ноль от dequeueReusableCellWithIdentifier? - PullRequest
6 голосов
/ 21 марта 2012

Я создал прототипную ячейку с идентификатором "mainViewTableCell" в файле раскадровки и соединил основную таблицу с классом пользовательского контроллера с именем "NTTableViewController". Я реализовал функцию "tableView cellForRowAtIndexPath" в NTTableViewController.m следующим образом:


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString* MAINVIEW_CELLIDENTIFIER = @"mainViewTableCell";
    UITableViewCell *newCell = [tableView dequeueReusableCellWithIdentifier: MAINVIEW_CELLIDENTIFIER];

    if (newCell == nil) {
        newCell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: MAINVIEW_CELLIDENTIFIER];
        [newCell autorelease];
        newCell.selectionStyle = UITableViewCellSelectionStyleNone;
    }

    NTContactItem* currentItem = [self.contactItemContainer objectInContainerAtIndex: indexPath.row];
    NSString* firstName = currentItem.firstName;
    NSString* lastName = currentItem.lastName;

    NSString* fullName = [firstName stringByAppendingFormat: lastName];    
    [newCell.textLabel setText: fullName];
    [newCell.detailTextLabel setText: currentItem.mobilePhone];

    return newCell;
}

Но я продолжаю получать ноль от dequeueReusableCellWithIdentifier и должен каждый раз создавать новый экземпляр ячейки.

Тогда что не так?

код: проект

Спасибо всем заранее.

Ответы [ 5 ]

26 голосов
/ 21 марта 2012

С раскадровками и табличными представлениями, имеющими ячейки-прототипы, [tableView dequeueReusableCellWithIdentifier:] не должно возвращать ноль.Даже если это самая первая ячейка, и в очереди на повторное использование уже нет ячеек, просмотр таблицы создаст новый экземпляр ячейки-прототипа и вернет его.

В вашем случае проблема заключалась в том, что проблема была полностьюдругой (я скачал ваш проект, потому что мне было очень любопытно).

В делегате вашего приложения в вашем методе application:didFinishLaunchingWithOptions: вы повторно инициализируете этот tableviewcontroller.Когда вы вызываете [masterController init], это вызывает [super init], что, в свою очередь, вызывает [UITableViewController initWithStyle:].

, что заставляет контроллер создавать новый UITableView, который отличается от того, что в вашей раскадровке.Этот новый UITableView не имеет ячеек-прототипов, и поэтому dequeueReusableCellWithIdentifier: возвращает ноль.

Урок, конечно, состоит в том, чтобы не повторно инициализировать объект Objective C, который уже был инициализирован.Когда ваш контроллер табличного представления загружается из раскадровки, механизм загрузки инициализирует его с initWithCoder:.Поэтому, если вам нужно выполнить какую-то пользовательскую инициализацию (например, настроить NSMutableArray в вашем случае), просто переопределите initWithCoder: и / или awakeFromNib.

Вы можете переопределить эти методы по мере необходимости, но не вызывайте их сами.И initWithCoder:, и awakeFromNib будут вызываться механизмом загрузки раскадровки / пера.

Если все правильно, вам не нужно создавать ячейки здесь программно.Этот бит кода не нужен:

// This bit is unnecessary with storyboards:      
if (newCell == nil) {
    newCell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: MAINVIEW_CELLIDENTIFIER];
    [newCell autorelease];
    newCell.selectionStyle = UITableViewCellSelectionStyleNone;
}

Надеюсь, это поможет.

2 голосов
/ 25 августа 2013

Прочитав ответ @ Фироза, я исправил свою проблему, которая преследовала меня несколько дней ... и нашел другое решение.Я знаю, что на этот вопрос уже был дан ответ, но это может кому-то помочь.

В моем случае я провел некоторый рефакторинг (извлек новый TableViewController), и после этого я получал ноль ячеек, возвращенных из dequeueReusableCellWithIdentifier.

Исправление для меня состояло в том, чтобы сделать это вместо вызова alloc/init на моем ViewController в didSelectRowAtIndexPath:

UIStoryboard*  sb = [UIStoryboard storyboardWithName:@"MainStoryboard"
                                              bundle:nil];

MyTableViewController* controller = [sb instantiateViewControllerWithIdentifier:
                                    @"MyTableViewController"];

(Тогда я вызываю [self.navigationController pushViewController:controller animated:YES]; - возможно, не самым чистым способом, ноэто работает)

1 голос
/ 04 марта 2014

На всякий случай это может кому-нибудь помочь в будущем ... В моем случае я забыл изменить в TableView (Storyboard) Content с «Статических ячеек» на «Динамические прототипы».

1 голос
/ 21 марта 2012

Ячейки таблицы могут использоваться повторно только в том случае, если они скрыты, поэтому в памяти должно быть только количество ячеек, отображаемых в данный момент.Сколько ячеек вы отображаете и сколько выделено?

0 голосов
/ 22 июля 2015

Типичная причина:

[tableView dequeueReusableCellWithIdentifier: @"id"]; не соответствует Xcode> Инспектор атрибутов> Ячейка табличного представления > Идентификатор > id

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...