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 Reader[4390:c07] *断言失败 -[UITableView dequeueReusableCellWithIdentifier:forIndexPath:], /SourceCache/UIKit_Sim/UIKit-2372/UITableView. [UITableView dequeueReusableCellWithIdentifier:forIndexPath:]m: 4460 2012-10-04 20:13:05.357 Reader[4390:c07] *由于未捕获而终止应用程序 exception 'NSInternalInconsistencyException',原因:'无法 必须注册一个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。终止调用抛出异常

下面是它在错误屏幕上显示的代码:

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

请帮助!

181732 次浏览

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

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

你没有为重用标识符"Cell"注册一个nib或类。

看看你的代码,你似乎期望dequeue方法返回nil,如果它没有一个单元格给你。你需要为该行为使用dequeueReusableCellWithIdentifier::

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

注意dequeueReusableCellWithIdentifier:dequeueReusableCellWithIdentifier:forIndexPath:是不同的方法。后者参见doc。

如果你想了解为什么你想要使用dequeueReusableCellWithIdentifier:forIndexPath:看看这个问答

我只会添加Xcode 4.5包含新的dequeueReusableCellWithIdentifier:forIndexPath:
在它的默认模板代码中-对于希望使用旧的dequeueReusableCellWithIdentifier:方法的开发人员来说,这是一个潜在的问题。< / p >

我也有同样的问题

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


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


}

解决了

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

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

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

这对我很有效。希望能有所帮助。

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

如果你要使用自定义静态单元格,只需注释这个方法:

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

并在storyboard中为单元格提供“属性检查器”的标识符。

我昨晚花了几个小时来解决为什么我的编程生成的表崩溃了[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上,这个按钮必须与IBAction和IBOutlet链接起来。

UIPopoverController *popoverController3在H文件中直接声明在@interface between{}之后

虽然这个问题相当古老,但还有另一种可能性: 如果你正在使用故事板,你只需要在故事板中设置CellIdentifier 所以如果你的CellIdentifier是"Cell",只需设置"Identifier"属性: enter image description here

确保在此之后清理构建。XCode有时在故事板更新方面会有一些问题

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

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

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

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

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

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

好事发生了!UITableViewController将自动注册你在storyboard中定义的自定义tableview单元格。

在你的委托方法"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将自动为您创建新的单元格。

那么你就完成了!

FWIW,当我忘记在故事板中设置单元格标识符时,我得到了同样的错误。如果这是您的问题,那么在故事板中单击表格视图单元格,并在属性编辑器中设置单元格标识符。确保您在这里设置的单元格标识符与

static NSString *CellIdentifier = @"YourCellIdenifier";

我在故事板中正确地设置了一切,并做了一个干净的构建,但一直得到错误“必须为标识符注册nib或类或连接故事板中的原型单元格吗

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

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

对某些人来说,这可能很愚蠢,但我明白了。我得到了这个错误,我的问题是,我试图使用静态单元格,但动态添加更多的东西。如果你调用这个方法,你的单元格需要是动态原型。选择storyboard中的单元格,在Attributes检查器下,第一个内容是“Content”,你应该选择动态原型,而不是静态原型。

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

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

也许它会对其他人有用。

Swift 2.0解决方案:

你需要进入你的属性检查器,为你的单元格添加一个名称:

enter image description here

然后你需要让你的标识符与你的出队列匹配,就像这样:

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 从指定的重用标识符上注销类

下面是苹果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)

只是答案的补充: 可能有一段时间你把所有的事情都纠正了,但你可能不小心在你的.xib中添加了一些其他的ui,比如UIButton:enter image description here 只要删除额外的UI,它就工作了

在我的情况下,崩溃发生时,我调用__abc0

这一行是[tableView deselectRowAtIndexPath:indexPath animated:YES];

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

希望这对大家有所帮助

在Swift中,这个问题可以通过添加以下代码来解决

viewDidLoad

方法。

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

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

如果我们使用dequeueReusableCellWithIdentifier:forIndexPath:,我们必须在调用这个方法as之前使用registerNib:forCellReuseIdentifier:或registerClass:forCellReuseIdentifier:方法注册一个类或nib文件 苹果文档说 < / p >

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

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

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

Objective - C

选项1:

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

选项2:

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

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

斯威夫特

选项1:

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

选项2:

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

在上面的代码nibName:"NameInput"给出你的nib名称

使用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
}

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

遇到这个错误bc单元复用标识符是错误的-一个新手错误,但它发生了: 1. 确保单元格重复使用标识符没有拼写错误或缺少字母。 2. 同样的,不要忘记大写的重要性。 3.0不是O (Ohs)

你必须意识到,当使用interface builder并创建包含一个单元格的Xib (nib)时,还会创建一个指向将要使用的类的placeholder。这意味着,当你在一个Xib文件中放置两个UITableViewCell时,你可能会遇到导致*** Assertion failure ...的完全相同的麻烦。占位符机制不起作用,n会感到困惑。取而代之的是在一个Xib中放置不同的占位符。

最简单的解决方案(即使这看起来有点简单)是将一个细胞放在一气呵成。IB将为您创建一个占位符,然后所有工作都按照预期进行。但是这将直接导致额外的一行代码,因为您需要加载正确的nib/xib,并请求它所在的reuseIdentified Cell。 因此,下面的示例代码着重于在一个表视图中使用多个单元格标识符,断言失败是非常常见的
// 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的另一个麻烦是必须考虑行高和/或节高。两个单元格当然可以有不同的高度。

当为重用注册类时,代码看起来应该不同。

“简单的解决方案”;当你的单元格位于故事板而不是Xib的内部时,看起来也有很大的不同。注意占位符。

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