324

所以我正在为我的学校制作一个 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 的单元格出列 - 必须为标识符注册一个 nib 或一个类或连接故事板中的原型单元格' *第一掷调用堆栈:(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:终止调用抛出异常

这是它在错误屏幕中显示的代码:

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

请帮忙!

4

22 回答 22

488

您正在使用该dequeueReusableCellWithIdentifier:forIndexPath:方法。该方法的文档说明了这一点:

重要提示:在调用此方法之前,您必须使用registerNib:forCellReuseIdentifier:or方法注册类或 nib 文件。registerClass:forCellReuseIdentifier:

您没有为重用标识符注册 nib 或类"Cell"

查看您的代码,您似乎希望 dequeue 方法在nil没有单元格可以返回时返回。您需要使用该dequeueReusableCellWithIdentifier:行为:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

请注意dequeueReusableCellWithIdentifier:dequeueReusableCellWithIdentifier:forIndexPath:是不同的方法。有关前者后者,请参见 doc 。

如果您想了解为什么要使用dequeueReusableCellWithIdentifier:forIndexPath:请查看此问答

于 2012-10-05T00:37:35.427 回答
138

我认为这个错误是关于为标识符注册你的笔尖或类。

这样您就可以在 tableView:cellForRowAtIndexPath 函数中保留您正在做的事情,只需将以下代码添加到您的 viewDidLoad 中:

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

它对我有用。希望它可能会有所帮助。

于 2012-12-13T09:42:13.443 回答
69

虽然这个问题已经相当老了,但还有另一种可能性:如果您使用的是 Storyboard,您只需在 Storyboard 中设置 CellIdentifier。

因此,如果您的 CellIdentifier 是“Cell”,只需设置“Identifier”属性: 在此处输入图像描述

确保在这样做之后清理你的构建。XCode 有时会在 Storyboard 更新方面出现一些问题

于 2013-02-18T15:36:17.543 回答
59

我有同样的问题替换

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

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

    }

解决了

于 2012-10-26T06:24:31.930 回答
27

问题很可能是因为您UITableViewCell在 storyboard 中配置了 custom 但您没有使用 storyboard 来实例化您UITableViewController使用 this的UITableViewCell。例如,在 MainStoryboard 中,您有一个名为的UITableViewController子类和一个名为“MyCell”MyTableViewController的自定义动态。UITableViewCellMyTableViewCell

如果您UITableViewController像这样创建自定义:

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

它不会自动为您注册您的自定义 tableviewcell。您必须手动注册它。

但是如果你使用 storyboard 来实例化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 将自动为您创建新单元格。

然后你就完成了!

于 2013-06-14T17:38:36.953 回答
19

我将补充一点,Xcode 4.5在其默认模板代码中包含新的 - 对于期待旧方法 dequeueReusableCellWithIdentifier:forIndexPath:
的开发人员来说,这是一个潜在的陷阱。dequeueReusableCellWithIdentifier:

于 2012-10-12T19:25:48.383 回答
18

在情节提要中,您应该将原型单元格的“标识符”设置为与 CellReuseIdentifier“单元格”相同。然后您将不会收到该消息或需要调用该 registerClass: 函数。

于 2013-01-03T23:43:44.813 回答
18

斯威夫特 2.0 解决方案:

您需要进入属性检查器并为您的单元格标识符添加一个名称:

在此处输入图像描述

然后你需要让你的标识符与你的出队匹配,如下所示:

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

或者

如果您正在使用 nib,您可能需要在 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 类参考说:

在将任何单元格出列之前,调用此方法或 registerNib:forCellReuseIdentifier: 方法来告诉表格视图如何创建新单元格。如果指定类型的单元格当前不在重用队列中,则表格视图使用提供的信息自动创建新的单元格对象。

如果您之前使用相同的重用标识符注册了类或 nib 文件,则您在 cellClass 参数中指定的类将替换旧条目。如果你想从指定的重用标识符中注销类,你可以为 cellClass 指定 nil。

以下是 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)
于 2015-06-12T18:30:05.627 回答
3

如果您要使用自定义静态单元格,只需评论此方法:

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

并在情节提要的“属性检查器”处为单元格指定一个标识符。

于 2013-02-05T04:52:06.537 回答
3

我在 Objective C 和 Swift 中都给你答案。在此之前我想说

如果我们使用dequeueReusableCellWithIdentifier:forIndexPath:,我们必须在调用此方法之前使用 registerNib:forCellReuseIdentifier: 或 registerClass:forCellReuseIdentifier: 方法注册一个类或 nib 文件,如 Apple Documnetation 所说

所以我们添加registerNib:forCellReuseIdentifier: or registerClass:forCellReuseIdentifier:

一旦我们为指定的标识符注册了一个类并且必须创建一个新单元格,此方法通过调用其 initWithStyle:reuseIdentifier: 方法来初始化该单元格。对于基于 nib 的单元格,此方法从提供的 nib 文件加载单元格对象。如果现有单元格可供重用,则此方法将改为调用该单元格的 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

迅速

选项1:

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

选项 2:

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

在上面的代码中nibName:"NameInput"给出你的笔尖名称

于 2016-08-23T06:34:26.177 回答
3

使用 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
}
于 2016-09-26T18:37:30.717 回答
2

昨晚我花了几个小时弄清楚为什么我以编程方式生成的表在 [myTable setDataSource:self] 上崩溃了;可以注释掉并弹出一个空表,但是每次我尝试访问数据源时都会崩溃;

我在 h 文件中设置了委派:@interface myViewController : UIViewController

我的实现中有数据源代码,但仍然 BOOM!,每次都崩溃!谢谢“xxd”(nr 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之后

于 2013-02-17T09:54:23.390 回答
2

FWIW,当我忘记在情节提要中设置单元格标识符时,我遇到了同样的错误。如果这是您的问题,那么在情节提要中单击表格视图单元格并在属性编辑器中设置单元格标识符。确保您在此处设置的单元格标识符与

static NSString *CellIdentifier = @"YourCellIdenifier";
于 2013-09-14T05:26:07.720 回答
2

我在情节提要中正确设置了所有内容并进行了干净的构建,但不断收到错误“必须为标识符注册笔尖或类或在情节提要中连接原型单元

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

纠正了错误,但我仍然不知所措。我没有使用“自定义单元格”,只是一个嵌入了 tableview 的视图。我已将视图控制器声明为委托和数据源,并确保单元格标识符在文件中匹配。这里发生了什么?

于 2013-10-23T20:03:05.090 回答
2

我有同样的问题,有同样的错误,对我来说它是这样工作的:

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

也许它对其他人有用。

于 2014-06-24T11:22:00.473 回答
1

这对某些人来说可能看起来很愚蠢,但它让我明白了。我收到了这个错误,对我来说问题是我试图使用静态单元格,然后动态添加更多内容。如果您调用此方法,您的单元格需要是动态原型。选择情节提要中的单元格并在属性检查器下,第一件事是“内容”,您应该选择动态原型而不是静态的。

于 2014-01-16T18:12:47.723 回答
1

只是答案的补充:可能有一段时间你把所有的东西都设置好了,但你可能会不小心在你身上添加了一些其他的 UI .xib,比如UIButton在此处输入图像描述 只需删除额外的 UI,它就可以工作。

于 2015-12-25T15:00:07.033 回答
1

确保故事板中单元格的 CellIdentifier == 标识符,两个名称相同。希望这对你有用

于 2017-01-17T09:49:01.427 回答
0

就我而言,当我打电话时发生了崩溃deselectRowAtIndexPath:

这条线是[tableView deselectRowAtIndexPath:indexPath animated:YES];

将其更改为解决了[self.tableView deselectRowAtIndexPath:indexPath animated:YES]; 我的问题!

希望这对任何人都有帮助

于 2016-03-02T22:34:29.077 回答
0

在 Swift 中,这个问题可以通过在你的

viewDidLoad

方法。

tableView.registerClass(UITableViewCell.classForKeyedArchiver(), forCellReuseIdentifier: "your_reuse_identifier")
于 2016-06-19T05:37:02.220 回答
0

您必须注意,在使用interface builder和创建包含一个Xib单元格的(笔尖)时,还会创建一个指向将要使用的类的单元格。这意味着,当您将两个放在一个 Xib 文件中时,您可能会遇到完全相同的问题,从而导致. 占位符机制不起作用,然后会感到困惑。而是在一个 Xib 中放置不同的占位符。placeholderUITableViewCell*** Assertion failure ...

最简单的解决方案(即使这看起来有点简单)是一次将一个 Cell放在一个 Xib中。IB 将为您创建一个占位符,然后所有工作都按预期进行。但这会直接导致一行额外的代码,因为您需要加载正确的 nib/xib 以请求其所在的重用标识单元。因此,以下示例代码集中在一个表视图中使用多个单元标识符,其中断言失败很常见。

// possibly above class implementation
static NSString *firstCellIdentifier = @"firstCellIdentifier";
static NSString *secondCellIdentifier = @"secondCellIdentifier";

// possibly in -(instancetype)init 
UINib *firstNib = [UINib nibWithNibName:@"FirstCell" bundle:nil];
[self.tableView registerNib:firstNib forCellReuseIdentifier:firstCellIdentifier];
UINib *secondNib = [UINib nibWithNibName:@"SecondCell" bundle:nil];
[self.tableView registerNib:secondNib forCellReuseIdentifier:secondCellIdentifier];

在一个 UITableView 中使用两个 CellIdentifier 的另一个问题是必须注意行高和/或节高。当然,两个单元格可以有不同的高度。

在注册类以供重用时,代码应该看起来不同。

当您的单元位于 Storyboard 而不是 Xib 中时,“简单解决方案”看起来也大不相同。注意占位符。

还要记住,界面构建器文件具有版本变化,需要设置为您的目标操作系统版本支持的版本。即使您可能很幸运,您在 Xib 中放置的特定功能自上一个 IB 版本以来没有更改,并且还没有引发错误。因此,使用 IB 制作的 Xib 设置为兼容iOS 13+但用于在早期版本上编译的目标iOS 12.4也会引起麻烦,并可能导致断言失败。

于 2020-09-16T05:50:18.150 回答
-1

遇到此错误,因为单元格重用标识符错误 - 一个新手错误,但它发生了: 1. 确保单元格重用标识符没有拼写错误或缺少字母。2. 同样,不要忘记大小写计数。3. 零不是“O”(哦)

于 2019-07-06T13:31:36.750 回答