UITableView Пользовательская Ошибка SIGABRT Броска ячейки - PullRequest
5 голосов
/ 20 февраля 2012

Я пытаюсь создать пользовательскую ячейку для своего UITableView.Я использую Xcode 4.2 и использую раскадровку вместе с ARC.

Я создал класс для представления пользовательской ячейки следующим образом:

ResultsCustomCell.h

#import <UIKit/UIKit.h>

@interface ResultsCustomCell : UITableViewCell
{
    IBOutlet UILabel *customLabel;
}

@property (nonatomic, retain) IBOutlet UILabel* customLabel;

@end

ResultsCustomCell.m

#import "ResultsCustomCell.h"

@implementation ResultsCustomCell

@synthesize customLabel;

@end

Затем я реализовал метод UITableView в моем контроллере представления следующим образом: ViewController.m

#import "ViewController.h"
#import "ResultsCustomCell.h"

@implementation ViewController

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
}

// Set the number of items in the tableview to match the array count
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{   
    return 5;
}

// Populate TableView cells with contents of array.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"CellIdentifier";

    ResultsCustomCell *myCell = [tableView dequeueReusableCellWithIdentifier:@"CellIdentifier"];
    myCell.customLabel.text = @"helloWorld";

    return myCell;
}

// Define height for cell.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 80;
}

@end

Приложение успешно собирается, но затем мгновенно падает, и выдает следующую ошибку:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'

Какую часть я пропускаю?

Ответы [ 7 ]

20 голосов
/ 25 июля 2013

Это раздражающая проблема, потому что отладчик не дает понять, что произошло. Он прервется на исключение и затем просто выключится, если вы нажмете «Продолжить выполнение».

Это сводило меня с ума в течение 30 минут, пока я не щелкнул правой кнопкой мыши на UILabel в пользовательской ячейке, которая доставляла мне проблемы, что показало ответ: один из элементов управления в вашей ячейке имеет (или имел, как вы, очевидно, исправили, возможно, не замечая) ложный выход. Под «ложной розеткой» я подразумеваю ту, которая связана со свойством IBOutlet, которого больше нет в вашем классе. В моем случае я изменил название объекта и подключил его заново, но забыл удалить старое соединение с выходной ссылкой.

Как только я удалил неисправную розетку, проблема ушла.

2 голосов
/ 20 февраля 2012

Вы забыли добавить идентификатор повторного использования ("CellIdentifier") в раскадровку к вашей ячейке-прототипу, поэтому, когда он пытается создать новую ячейку, в раскадровке нет прототипа с этим идентификатором, и он возвращает nil.

2 голосов
/ 20 февраля 2012

Вы забыли создать новый UITableViewCell, когда он не удален из очереди

// Populate TableView cells with contents of array.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"CellIdentifier";

    ResultsCustomCell *myCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (myCell == nil) {
        myCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
    myCell.customLabel.text = @"helloWorld";

    return myCell;
}
1 голос
/ 20 февраля 2012

Я не совсем уверен, что я сделал, чтобы решить мою проблему, но теперь он работает правильно.

Вот то, что у меня сейчас есть в моем ViewController.m

Примечание: ResultsCustomCell.h и .m такие же, как указано выше.

#import "ViewController.h"
#import "ResultsCustomCell.h"

@implementation ViewController

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];   
}

// Set the number of items in the tableview to match the array count
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{   
    return 5;
}

// Populate TableView cells with contents of array.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"CellIdentifier";

    // Make sure there are no quotations (") around the cell Identifier.
    ResultsCustomCell *myCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    myCell.customLabel.text = @"helloWorld";

    return myCell;
}

// Define height for cell.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 80;
}

@end

Затем я удостоверился в правильности следующих вещей:

  • В ячейке табличного представления указан правильный пользовательский класс (ResultsCustomCell).
  • Идентификатор ячейки для UITableViewCell был правильным в Интерфейсном Разработчике.
  • UILabel в конструкторе интерфейсов был правильно связан с IBOutlet.
  • У представления UITableView был правильный контроллер (ViewController)

После использования этого кода и проверки всего вышеперечисленного он работает.

1 голос
/ 20 февраля 2012
@property (nonatomic, retain) IBOutlet UILabel* customLabel;

Автоматический подсчет ссылок (ARC) запрещает явный вызов retain. Попробуйте удалить это.

Что касается ошибки, вы возвращаете UITableViewCell, а не свою пользовательскую ячейку. Кроме того, вы никогда не выделяете свой ResultsCustomCell.

- (ResultsCustomCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"CellIdentifier";

    ResultsCustomCell *cell = (ResultsCustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[ResultsCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // Configure the cell.
    cell.textLabel.text = @"Text";
    return cell;
}

Кроме того, ваш подкласс UITableViewCell не объявляет (очевидно обязательный) метод init.

ResultsCustomCell.h:

#import <UIKit/UIKit.h>

@interface ResultsCustomCell : UITableViewCell

@property (strong, nonatomic) UILabel *myLabel;

@end

ResultsCustomCell.m:

#import "ResultsCustomCell.h"

@implementation ResultsCustomCell

@synthesize myLabel;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code
    }
    return self;
}

@end

РЕДАКТИРОВАТЬ: Я видел, что вы используете раскадровку. Мое предложение может или не может быть полезным для вас. Я никогда не использовал раскадровку.

0 голосов
/ 15 мая 2019

Я создал это исключение, по ошибке зарегистрировав идентификатор с неправильным типом класса.

//The Identifier is register with the wrong class type
self.listView.register(CustomCellClass1.self, forCellReuseIdentifier: "CustomCellClass2")

И затем сняв в очередь и приведя к другому типу класса:

let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCellClass2", for: indexPath) as! CustomCellClass2
0 голосов
/ 09 декабря 2012

Я также боролся с этой ошибкой с той же настройкой, что и ваша. Я понял, что это, для меня, было вызвано новой функцией «Auto layout» iOS6. Чтобы отключить его, я открыл пользовательскую ячейку XIB, а затем в правой части Утилиты открыл вкладку «Инспектор файлов» (крайняя левая вкладка). Там я мог снять галочку с «Использовать Autolayout».

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