ios dequeueReusableCellWithIdentifier:forIndexPath 中的断言失败:

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12737860/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:36:33  来源:igfitidea点击:

Assertion failure in dequeueReusableCellWithIdentifier:forIndexPath:

iosobjective-cuitableview

提问by Nick Scottman

So I was making an rss reader for my school and finished the code. I ran the test and it gave me that error. Here is the code it's referring to:

所以我正在为我的学校制作一个 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];

    }

here's the error in the output:

这是输出中的错误:

2012-10-04 20:13:05.356 Reader[4390:c07] * Assertion failure in -[UITableView dequeueReusableCellWithIdentifier:forIndexPath:], /SourceCache/UIKit_Sim/UIKit-2372/UITableView.m:4460 2012-10-04 20:13:05.357 Reader[4390:c07] *Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier Cell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard' *First throw call stack: (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 called throwing an exception

2012-10-04 20:13:05.356 Reader[4390:c07] * 断言失败 -[UITableView dequeueReusableCellWithIdentifier:forIndexPath:],/SourceCache/UIKit_Sim/UIKit-2372/UITableView.m:4460-10-2014 13:05.357 Reader[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: 终止调用抛出异常

and here's the code it shows in the error screen:

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

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

please help!

请帮忙!

回答by rob mayoff

You're using the dequeueReusableCellWithIdentifier:forIndexPath:method. The documentationfor that method says this:

您正在使用该dequeueReusableCellWithIdentifier:forIndexPath:方法。该方法的文档是这样说的:

Important:You must register a class or nib file using the registerNib:forCellReuseIdentifier:or registerClass:forCellReuseIdentifier:method before calling this method.

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

You didn't register a nib or a class for the reuse identifier "Cell".

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

Looking at your code, you seem to expect the dequeue method to return nilif it doesn't have a cell to give you. You need to use the dequeueReusableCellWithIdentifier:for that behavior:

查看您的代码,您似乎希望 dequeue 方法在nil没有单元格给您的情况下返回。您需要将dequeueReusableCellWithIdentifier:用于该行为:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

Notice that dequeueReusableCellWithIdentifier:and dequeueReusableCellWithIdentifier:forIndexPath:are different methods. See doc for the formerand the latter.

请注意,dequeueReusableCellWithIdentifier:dequeueReusableCellWithIdentifier:forIndexPath:是不同的方法。前者后者见文档。

If you want to understand why you'd want to ever use dequeueReusableCellWithIdentifier:forIndexPath:, check out this Q&A.

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

回答by Nick Scottman

I think this error is about registering your nib or class for the identifier.

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

So that you may keep what you are doing in your tableView:cellForRowAtIndexPath function and just add code below into your viewDidLoad:

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

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

It's worked for me. Hope it may help.

它对我有用。希望它可以帮助。

回答by Sebastian Borggrewe

Although this question is fairly old, there is another possibility: If you are using Storyboards, you simply have to set the CellIdentifier in the Storyboard.

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

So if your CellIdentifier is "Cell", just set the "Identifier" property: enter image description here

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

Make sure to clean your build after doing so. XCode sometimes has some issues with Storyboard updates

要确保这样做后清洁你的身材。XCode 有时在 Storyboard 更新方面存在一些问题

回答by iMeMyself

i had the same problem replacing with

我有同样的问题替换

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

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

    }

solved

解决了

回答by James Wang

The problem is most likely because you config custom UITableViewCellin storyboard but you do not use storyboard to instantiate your UITableViewControllerwhich uses this UITableViewCell. For example, in MainStoryboard, you have a UITableViewControllersubclass called MyTableViewControllerand have a custom dynamic UITableViewCellcalled MyTableViewCellwith identifier id "MyCell".

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

If you create your custom UITableViewControllerlike this:

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

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

It will not automatically register your custom tableviewcell for you. You have to manually register it.

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

But if you use storyboard to instantiate MyTableViewController, like this:

但是如果你使用 storyboard 来实例化MyTableViewController,就像这样:

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

Nice thing happens! UITableViewControllerwill automatically register your custom tableview cell that you define in storyboard for you.

好事发生了!UITableViewController将自动注册您在故事板中为您定义的自定义 tableview 单元格。

In your delegate method "cellForRowAtIndexPath", you can create you table view cell like this :

在您的委托方法“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 will automatically create new cell for you if there is not reusable cell available in the recycling queue.

如果回收队列中没有可用的可重用单元,dequeueReusableCellWithIdentifier 将自动为您创建新单元。

Then you are done!

然后你就完成了!

回答by Brian Shriver

I'll just add that Xcode 4.5includes the new dequeueReusableCellWithIdentifier:forIndexPath:
in its default template code - a potential gotcha for developers expecting the older dequeueReusableCellWithIdentifier:method.

我只想补充一点,Xcode 4.5dequeueReusableCellWithIdentifier:forIndexPath:
在其默认模板代码中包含了新的- 对于期望使用旧dequeueReusableCellWithIdentifier:方法的开发人员来说,这是一个潜在的问题。

回答by Steven

In your storyboard you should set the 'Identifier' of your prototype cell to be the same as your CellReuseIdentifier "Cell". Then you won't get that message or need to call that registerClass: function.

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

回答by Dan Beaulieu

Swift 2.0 solution:

Swift 2.0 解决方案:

You need to go into your Attribute Inspector and add a name for your cells Identifier:

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

enter image description here

在此处输入图片说明

Then you need to make your identifier match with your dequeue like this:

然后你需要像这样使你的标识符与你的出队匹配:

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

Alternatively

或者

If you're working with a nib you may need to register your class in your cellForRowAtIndexPath:

如果您使用笔尖,您可能需要在 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    
}

Apples's UITableView Class Reference says:

Apples 的 UITableView 类参考说:

Prior to dequeueing any cells, call this method or the registerNib:forCellReuseIdentifier: method to tell the table view how to create new cells. If a cell of the specified type is not currently in a reuse queue, the table view uses the provided information to create a new cell object automatically.

If you previously registered a class or nib file with the same reuse identifier, the class you specify in the cellClass parameter replaces the old entry. You may specify nil for cellClass if you want to unregister the class from the specified reuse identifier.

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

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

Here's the code from Apples Swift 2.0 framework:

这是来自 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)

回答by Francisco Gutiérrez

If you are going with Custom Static Cellsjust comment this method:

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

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

and give the cells an identifier at "Attributes Inspector"in storyboard.

并在故事板的“属性检查器”中为单元格提供一个标识符。

回答by user3182143

I give you the answer in both Objective C and Swift.Before that I want to say

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

If we use the dequeueReusableCellWithIdentifier:forIndexPath:,we must register a class or nib file using the registerNib:forCellReuseIdentifier: or registerClass:forCellReuseIdentifier: method before calling this method as Apple Documnetation Says

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

So we add registerNib:forCellReuseIdentifier: or registerClass:forCellReuseIdentifier:

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

Once we registered a class for the specified identifier and a new cell must be created, this method initializes the cell by calling its initWithStyle:reuseIdentifier: method. For nib-based cells, this method loads the cell object from the provided nib file. If an existing cell was available for reuse, this method calls the cell's prepareForReuse method instead.

一旦我们为指定的标识符注册了一个类并且必须创建一个新的单元格,这个方法就会通过调用它的 initWithStyle:reuseIdentifier: 方法来初始化单元格。对于基于 nib 的单元格,此方法从提供的 nib 文件加载单元格对象。如果现有单元格可供重用,则此方法将调用单元格的 prepareForReuse 方法。

in viewDidLoad method we should register the cell

在 viewDidLoad 方法中,我们应该注册单元格

Objective C

目标 C

OPTION 1:

选项1:

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

OPTION 2:

选项 2:

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

in above code nibWithNibName:@"CustomCell"give your nib name instead of my nib name CustomCell

在上面的代码中nibWithNibName:@"CustomCell"给出你的笔尖名称而不是我的笔尖名称 CustomCell

SWIFT

迅速

OPTION 1:

选项1:

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

OPTION 2:

选项 2:

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

in above code nibName:"NameInput"give your nib name

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