所以我正在为我的学校制作一个 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 或一个类或连接故事板中的原型单元格' * 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: 终止调用抛出异常
这是它在错误屏幕中显示的代码:
int main(int argc, char *argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
请帮忙!
您正在使用 dequeueReusableCellWithIdentifier:forIndexPath:
方法。该方法的 documentation 表示:
重要提示:在调用此方法之前,您必须使用 registerNib:forCellReuseIdentifier: 或 registerClass:forCellReuseIdentifier: 方法注册类或 nib 文件。
您没有为重用标识符 "Cell"
注册 nib 或类。
查看您的代码,您似乎希望 dequeue 方法返回 nil
如果它没有单元格可以给您。对于该行为,您需要使用 dequeueReusableCellWithIdentifier:
:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
请注意,dequeueReusableCellWithIdentifier:
和 dequeueReusableCellWithIdentifier:forIndexPath:
是不同的方法。请参阅 the former 和 the latter 的文档。
如果您想了解为什么要使用 dequeueReusableCellWithIdentifier:forIndexPath:
,check out this Q&A。
我认为这个错误是关于为标识符注册你的笔尖或类。
这样您就可以在 tableView:cellForRowAtIndexPath 函数中保留您正在做的事情,只需将以下代码添加到您的 viewDidLoad 中:
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];
它对我有用。希望它可能会有所帮助。
viewDidLoad
中,并将此逻辑移至 viewDidAppear
修复了它。
虽然这个问题已经相当老了,但还有另一种可能性:如果您使用的是 Storyboard,您只需在 Storyboard 中设置 CellIdentifier。
https://i.stack.imgur.com/uBGUN.png
确保在这样做之后清理你的构建。 XCode 有时会在 Storyboard 更新方面出现一些问题
Identifier
属性后,清理构建是必不可少的。谢谢!
我有同样的问题替换
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell==nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
解决了
问题很可能是因为您在情节提要中配置了自定义 UITableViewCell
,但您没有使用情节提要来实例化使用此 UITableViewCell
的 UITableViewController
。例如,在 MainStoryboard 中,您有一个名为 MyTableViewController
的 UITableViewController
子类和一个名为 MyTableViewCell
的自定义动态 UITableViewCell
,标识符 ID 为“MyCell”。
如果您像这样创建自定义 UITableViewController
:
MyTableViewController *myTableViewController = [[MyTableViewController alloc] init];
它不会自动为您注册您的自定义 tableviewcell。您必须手动注册它。
但如果您使用情节提要来实例化 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 将自动为您创建新单元格。
然后你就完成了!
instantiateViewControllerWithIdentifier
来初始化我的 viewController 的提示拯救了我的一天!
我将补充一点,Xcode 4.5 在其默认模板代码中包含新的 dequeueReusableCellWithIdentifier:forIndexPath:
- 对于期待旧 dequeueReusableCellWithIdentifier:
方法的开发人员来说,这是一个潜在的陷阱。
在情节提要中,您应该将原型单元格的“标识符”设置为与 CellReuseIdentifier“单元格”相同。然后您将不会收到该消息或需要调用该 registerClass: 函数。
斯威夫特 2.0 解决方案:
您需要进入属性检查器并为您的单元格标识符添加一个名称:
https://i.stack.imgur.com/Q9Miq.png
然后你需要让你的标识符与你的出队匹配,如下所示:
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
}
Apples's UITableView Class Reference says:
在将任何单元格出列之前,调用此方法或 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)
SwitchCell.self
来自哪里?
UITableViewCell.self
替换它似乎对我有用。也许在答案中添加注释
如果您要使用自定义静态单元格,只需评论此方法:
//- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// static NSString *CellIdentifier = @"notificationCell";
// UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// return cell;
//}
并在情节提要的“属性检查器”处为单元格指定一个标识符。
我在 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"
中给出你的笔尖名称
使用 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
}
昨晚我花了几个小时弄清楚为什么我以编程方式生成的表在 [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之后
FWIW,当我忘记在情节提要中设置单元格标识符时,我遇到了同样的错误。如果这是您的问题,那么在情节提要中单击表格视图单元格并在属性编辑器中设置单元格标识符。确保您在此处设置的单元格标识符与
static NSString *CellIdentifier = @"YourCellIdenifier";
我有同样的问题,有同样的错误,对我来说它是这样工作的:
[self.tableView registerNib:[UINib nibWithNibName:CELL_NIB_HERE bundle: nil] forCellReuseIdentifier:CELL_IDENTIFIER_HERE];
也许它对其他人有用。
我在情节提要中正确设置了所有内容并进行了干净的构建,但不断收到错误“必须为标识符注册笔尖或类或在情节提要中连接原型单元”
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];
纠正了错误,但我仍然不知所措。我没有使用“自定义单元格”,只是一个嵌入了 tableview 的视图。我已将视图控制器声明为委托和数据源,并确保单元格标识符在文件中匹配。这里发生了什么?
这对某些人来说可能看起来很愚蠢,但它让我明白了。我收到了这个错误,对我来说问题是我试图使用静态单元格,然后动态添加更多内容。如果您调用此方法,您的单元格需要是动态原型。选择情节提要中的单元格并在属性检查器下,第一件事是“内容”,您应该选择动态原型而不是静态的。
https://i.stack.imgur.com/vVwra.png
确保故事板中单元格的 CellIdentifier == 标识符,两个名称相同。希望这对你有用
就我而言,崩溃发生在我打电话时deselectRowAtIndexPath:
该行是 [tableView deselectRowAtIndexPath:indexPath animated:YES];
将其更改为 [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
解决了我的问题!
希望这对任何人都有帮助
在 Swift 中,这个问题可以通过在你的
viewDidLoad
方法。
tableView.registerClass(UITableViewCell.classForKeyedArchiver(), forCellReuseIdentifier: "your_reuse_identifier")
您必须注意,在使用 interface builder
并创建一个包含 一个 单元格的 Xib
(笔尖)时,还会创建一个指向将要使用的类的 placeholder
。这意味着,当您将两个 UITableViewCell
放在一个 Xib 文件中时,您可能会遇到完全相同的问题,从而导致 *** Assertion failure ...
。占位符机制不起作用,然后会感到困惑。而是在一个 Xib 中放置不同的占位符。
最简单的解决方案(即使这看起来有点简单)是在一个 Xib 中一次放置一个 Cell。 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 版本以来没有更改,并且还没有引发错误。因此,使用设置为与 iOS 13+
兼容的 IB 制作的 Xib 但用于在早期版本 iOS 12.4
上编译的目标也会引起麻烦并最终导致断言失败。
遇到此错误,因为单元格重用标识符错误 - 一个新手错误,但它发生了: 1. 确保单元格重用标识符没有拼写错误或缺少字母。 2. 同样,不要忘记大小写计数。 3. 零不是“O”(哦)
dequeueReusableCellWithIdentifer:forIndexPath:
(在 iOS6 中引入)是一个很好的改进,因为您不需要检查单元格是否为 nil。 (所以UITableViewController
的工作方式类似于UICollectionView
)但是,是的,令人讨厌的是,此更改没有在模板中注释,并且断言/崩溃消息没有更多帮助。dequeueReusableCellWithIdentifier:
时,我已经不止一次使用dequeueReusableCellWithIdentifier:forIndexPath:
被咬了。