it-roy-ru.com

Ошибка подтверждения в dequeueReusableCellWithIdentifier: forIndexPath:

Поэтому я делал rss-ридер для своей школы и закончил писать код. Я запустил тест, и он дал мне эту ошибку. Вот код, на который он ссылается:

- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = 
     [tableView dequeueReusableCellWithIdentifier:CellIdentifier 
                                     forIndexPath:indexPath];
    if (cell == nil) {

        cell = 
         [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle  
                                reuseIdentifier:CellIdentifier];

    }

вот ошибка в выводе:

2012-10-04 20: 13: 05.356 Считыватель [4390: c07] * Ошибка подтверждения в - [UITableView dequeueReusableCellWithIdentifier: forIndexPath:], /SourceCache/UIKit_Sim/UIKit-2372/UITableView.m:4460 2012-10 -04 20: 13: 05.357 Считыватель [4390: c07] * Завершение приложения из-за необработанного исключения "NSInternalInconsistencyException", причина: "невозможно удалить из очереди ячейку с идентификатором Cell - необходимо зарегистрировать перо или класс для идентификатора или подключить ячейку прототип в раскадровке" * Первый стек бросить вызов: (0x1c91012 0x10cee7e 0x1c90e78 0xb64f35 0xc7d14 0x39ff 0xd0f4b 0xd101f 0xb980b 0xca19b 0x6692d 0x10e26b0 0x228dfc0 0x228233c 0x228deaf 0x1058cd 0x4e1a6 0x4ccbf 0x4cbd9 0x4be34 0x4bc6e 0x4ca29 0x4f922 0xf9fec 0x46bc4 0x47311 0x2cf3 0x137b7 0x13da7 0x14fab 0x26315 0x2724b 0x18cf8 0x1becdf9 0x1becad0 0x1c06bf5 0x1c06962 0x1c37bb6 0x1c36f44 0x1c36e1b 0x147da 0x1665c 0x2a02 0x2935) Libc ++ abi.dylib: Terminate называется бросать исключение

и вот код, который он показывает на экране ошибки:

int main(int argc, char *argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

пожалуйста помоги!

317
Nick Scottman

Вы используете метод dequeueReusableCellWithIdentifier:forIndexPath:. документация для этого метода говорит следующее:

Важно: Вы должны зарегистрировать файл класса или пера, используя метод registerNib:forCellReuseIdentifier: или registerClass:forCellReuseIdentifier:, прежде чем вызывать этот метод.

Вы не зарегистрировали перо или класс для идентификатора повторного использования "Cell".

Глядя на свой код, вы, похоже, ожидаете, что метод dequeue вернет nil, если у него нет ячейки, чтобы дать вам. Вам нужно использовать dequeueReusableCellWithIdentifier: для этого поведения:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

Обратите внимание, что dequeueReusableCellWithIdentifier: и dequeueReusableCellWithIdentifier:forIndexPath: являются разными методами. Смотрите документ для первый и последний .

Если вы хотите понять, почему вы хотите использовать dequeueReusableCellWithIdentifier:forIndexPath:, ознакомьтесь с этими вопросами и ответами .

483
rob mayoff

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

Чтобы вы могли сохранить то, что вы делаете, в функции tableView: cellForRowAtIndexPath и просто добавить приведенный ниже код в ваш viewDidLoad:

[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];

Это сработало для меня. Надеюсь, это может помочь.

137
user843910

Хотя этот вопрос довольно старый, есть еще одна возможность: если вы используете раскадровки, вам просто нужно установить CellIdentifier в раскадровке.

Поэтому, если ваш CellIdentifier имеет значение "Cell", просто установите свойство "Identifier": enter image description here

После этого обязательно очистите сборку. Иногда в XCode возникают проблемы с обновлениями Storyboard

67
Sebastian Borggrewe

у меня была та же проблема с заменой на

static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

   if (cell==nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];

    }

решена

59
iMeMyself

Проблема, скорее всего, заключается в том, что вы настраиваете пользовательское UITableViewCell в раскадровке, но вы не используете раскадровку для создания экземпляра своего UITableViewController, который использует это UITableViewCell. Например, в MainStoryboard у вас есть подкласс UITableViewController с именем MyTableViewController и пользовательский динамический UITableViewCell с именем MyTableViewCell с идентификатором идентификатора "MyCell".

Если вы создаете свое собственное UITableViewController, как это:

 MyTableViewController *myTableViewController = [[MyTableViewController alloc] init];

Он не будет автоматически регистрировать вашу пользовательскую ячейку просмотра таблицы Вы должны вручную зарегистрировать его.

Но если вы используете раскадровку для создания экземпляра MyTableViewController, вот так:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
MyTableViewController *myTableViewController = [storyboard  instantiateViewControllerWithIdentifier:@"MyTableViewController"];

Хорошая вещь случается! UITableViewController автоматически зарегистрирует вашу пользовательскую ячейку таблицы, которую вы определили в раскадровке.

В вашем методе делегата "cellForRowAtIndexPath" вы можете создать ячейку табличного представления следующим образом:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"MyCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

//Configure your cell here ...

return cell;
}

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

Тогда вы сделали!

25
James Wang

Я просто добавлю, что Xcode 4.5 включает новый dequeueReusableCellWithIdentifier:forIndexPath:
в коде шаблона по умолчанию - потенциальная ошибка для разработчиков, ожидающих более старый метод dequeueReusableCellWithIdentifier:.

19
Brian Shriver

Решение Swift 2.0:

Вам необходимо зайти в инспектор атрибутов и добавить имя для ваших ячеек. Идентификатор:

enter image description here

Затем вам нужно сделать так, чтобы ваш идентификатор соответствовал вашей очереди:

let cell2 = tableView.dequeueReusableCellWithIdentifier("ButtonCell", forIndexPath: indexPath) as! ButtonCell

В качестве альтернативы

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

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {       

    tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "SwitchCell")

    // included for context            
    let cell = tableView.dequeueReusableCellWithIdentifier("SwitchCell", forIndexPath:indexPath) as! SwitchCell

    //... continue    
}

Ссылка на класс UITableView от Apple говорит:

Перед удалением из очереди любых ячеек вызовите этот метод или registerNib: forCellReuseIdentifier: метод, чтобы сообщить табличному представлению, как создавать новые ячейки. Если ячейка указанного типа в данный момент не находится в очереди на повторное использование, табличное представление использует предоставленную информацию для автоматического создания нового объекта ячейки.

Если вы ранее зарегистрировали файл класса или пера с тем же идентификатором повторного использования, класс, указанный в параметре cellClass, заменит старую запись. Вы можете указать nil для cellClass, если хотите отменить регистрацию класса по указанному идентификатору повторного использования.

Вот код из фреймворка Apples Swift 2.0:

// Beginning in iOS 6, clients can register a nib or class for each cell.
// If all reuse identifiers are registered, use the newer -dequeueReusableCellWithIdentifier:forIndexPath: to guarantee that a cell instance is returned.
// Instances returned from the new dequeue method will also be properly sized when they are returned.

@available(iOS 5.0, *)
func registerNib(nib: UINib?, forCellReuseIdentifier identifier: String)

@available(iOS 6.0, *)
func registerClass(cellClass: AnyClass?, forCellReuseIdentifier identifier: String)
18
Dan Beaulieu

В вашей раскадровке вы должны установить "Идентификатор" вашей ячейки-прототипа таким же, как ваш CellReuseIdentifier "Ячейка". Тогда вы не получите это сообщение или не будете вызывать эту функцию registerClass :.

18
Steven

Работа с Swift 3.0:

override func viewDidLoad() {
super.viewDidLoad()

self.myList.register(UINib(nibName: "MyTableViewCell", bundle: nil), forCellReuseIdentifier: "Cell")
}



public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = myList.dequeueReusableCell(withIdentifier: "Cell", for: indexPath as IndexPath) as! MyTableViewCell

return cell
}
3
norbDEV

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

//- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//    static NSString *CellIdentifier = @"notificationCell";
//    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
//    return cell;
//}

и дайте ячейкам идентификатор в "Инспектор атрибутов" в раскадровке.

3
Francisco Gutiérrez

Я даю вам ответ в Objective C и Swift. До этого я хочу сказать

Если мы используем dequeueReusableCellWithIdentifier:forIndexPath:, мы должны зарегистрировать файл класса или nib, используя registerNib: forCellReuseIdentifier: или registerClass: forCellReuseIdentifier: метод, прежде чем вызывать этот метод как Apple Documnetation Says

Поэтому мы добавляем registerNib:forCellReuseIdentifier: or registerClass:forCellReuseIdentifier:

Как только мы зарегистрировали класс для указанного идентификатора, и новая ячейка должна быть создана, этот метод инициализирует ячейку, вызывая ее метод initWithStyle: reuseIdentifier:. Для ячеек на основе пера этот метод загружает объект ячейки из предоставленного файла пера. Если существующая ячейка была доступна для повторного использования, этот метод вместо этого вызывает метод prepareForReuse ячейки.

в методе viewDidLoad мы должны зарегистрировать ячейку

Цель C

ВАРИАНТ 1:

[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"];

ВАРИАНТ 2:

[self.tableView registerNib:[UINib nibWithNibName:@"CustomCell" bundle:nil] forCellReuseIdentifier:@"cell"];

в приведенном выше коде nibWithNibName:@"CustomCell" укажите ваше имя пера вместо моего имени пера CustomCell

Swift

ВАРИАНТ 1:

tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")

ВАРИАНТ 2:

tableView.registerNib(UINib(nibName: "NameInput", bundle: nil), forCellReuseIdentifier: "Cell") 

в приведенном выше коде nibName:"NameInput" укажите имя пера

3
user3182143

Я правильно все настроил в раскадровке и выполнил чистую сборку, но продолжал получать сообщение об ошибке "необходимо зарегистрировать перо или класс для идентификатора или подключить ячейку прототипа в раскадровке"

[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];

Исправил ошибку, но я все еще в растерянности. Я не использую "пользовательскую ячейку", просто представление с вложенным табличным представлением. Я объявил viewcontroller как делегат и источник данных и убедился, что идентификатор файла совпадает в файле. что тут происходит?

2
FrostyL

FWIW, я получил эту же ошибку, когда я забыл установить идентификатор ячейки в раскадровке. Если это ваша проблема, то в раскадровке щелкните ячейку табличного представления и установите идентификатор ячейки в редакторе атрибутов. Убедитесь, что установленный здесь идентификатор ячейки совпадает с

static NSString *CellIdentifier = @"YourCellIdenifier";
2
honkskillet

У меня была та же проблема, была та же ошибка, и у меня это работало так:

[self.tableView registerNib:[UINib nibWithNibName:CELL_NIB_HERE bundle: nil] forCellReuseIdentifier:CELL_IDENTIFIER_HERE];

Может быть, это будет полезно для кого-то еще.

2
CarmenA

Прошлой ночью я потратил несколько часов на то, чтобы выяснить, почему моя программно сгенерированная таблица не работает [myTable setDataSource: self]; Это было нормально, комментируя и выскакивая пустую таблицу, но вылетало каждый раз, когда я пытался добраться до источника данных;

Я настроил делегирование в файле h: @interface myViewController: UIViewController

У меня был исходный код данных в моей реализации, и все равно BOOM !, каждый раз сбой! СПАСИБО "xxd" (номер 9): добавление этой строки кода решило это для меня! На самом деле я запускаю таблицу с кнопки IBAction, поэтому вот мой полный код:

    - (IBAction)tapButton:(id)sender {

    UIViewController* popoverContent = [[UIViewController alloc]init];

    UIView* popoverView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 300)];
    popoverView.backgroundColor = [UIColor greenColor];
    popoverContent.view = popoverView;

    //Add the table
    UITableView *table = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 200, 300)         style:UITableViewStylePlain];

   // NEXT THE LINE THAT SAVED MY SANITY Without it the program built OK, but crashed when      tapping the button!

    [table registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];
    table.delegate=self;
    [table setDataSource:self];
    [popoverView addSubview:table];
    popoverContent.contentSizeForViewInPopover =
    CGSizeMake(200, 300);

    //create a popover controller
    popoverController3 = [[UIPopoverController alloc]
                          initWithContentViewController:popoverContent];
    CGRect popRect = CGRectMake(self.tapButton.frame.Origin.x,
                                self.tapButton.frame.Origin.y,
                                self.tapButton.frame.size.width,
                                self.tapButton.frame.size.height);


    [popoverController3 presentPopoverFromRect:popRect inView:self.view   permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];



   }


   #Table view data source in same m file

   - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
   {
    NSLog(@"Sections in table");
    // Return the number of sections.
    return 1;
   }

   - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
  {
    NSLog(@"Rows in table");

    // Return the number of rows in the section.
    return myArray.count;
   }

   - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath    *)indexPath
    {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    NSString *myValue;

    //This is just some test array I created:
    myValue=[myArray objectAtIndex:indexPath.row];

    cell.textLabel.text=myValue;
    UIFont *myFont = [ UIFont fontWithName: @"Arial" size: 12.0 ];
    cell.textLabel.font  = myFont;

    return cell;
   }

Между прочим: кнопка должна быть связана как IBAction и как IBOutlet, если вы хотите привязать к нему всплывающее окно.

UIPopoverController * popoverController3 объявляется в файле H непосредственно после @interface между {}

2
Simone

Просто дополнение ответов: может быть, время, когда вы все настроите правильно, но вы можете случайно добавить некоторые другие интерфейсы в свой .xib, например, UIButton: enter image description here Просто удалите лишний интерфейс, все работает.

1
DrustZ

Убедитесь, что CellIdentifier == идентификатор ячейки в раскадровке, оба имени совпадают. Надеюсь, это работает для вас

1
Ankit garg

Некоторым это может показаться глупым, но я понял. Я получал эту ошибку, и проблема для меня заключалась в том, что я пытался использовать статические ячейки, но затем динамически добавлять больше материала. Если вы вызываете этот метод, ваши ячейки должны быть динамическими прототипами. Выберите ячейку в раскадровке и под инспектором Атрибутов самое первое говорит "Содержимое", и вы должны выбрать динамические прототипы, а не статические.

1
Chase Roberts

В Swift эту проблему можно решить, добавив следующий код в

viewDidLoad

метод.

tableView.registerClass(UITableViewCell.classForKeyedArchiver(), forCellReuseIdentifier: "your_reuse_identifier")
0
arango_86

В моем случае сбой произошел, когда я позвонил deselectRowAtIndexPath:

Строка была [tableView deselectRowAtIndexPath:indexPath animated:YES];

Изменив его на [self.tableView deselectRowAtIndexPath:indexPath animated:YES];ИСПРАВЛЕНО МОЯ ПРОБЛЕМА!

Надеюсь, это кому-нибудь поможет

0
Offek