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出列单元 – 必须为标识符注册一个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:terminate调用抛出异常
以下是错误屏幕中显示的代码:
int main(int argc, char *argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } }
请帮忙!
您正在使用dequeueReusableCellWithIdentifier:forIndexPath:
方法。 该方法的文档说明了这一点:
重要:在调用此方法之前,必须使用
registerNib:forCellReuseIdentifier:
或registerClass:forCellReuseIdentifier:
方法注册类或nib文件。
您没有为重用标识符"Cell"
注册一个笔尖或类。
看看你的代码,如果没有一个单元给你,你似乎期望出列方法返回nil
。 您需要使用dequeueReusableCellWithIdentifier:
对于该行为:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
注意dequeueReusableCellWithIdentifier:
和dequeueReusableCellWithIdentifier:forIndexPath:
是不同的方法。 前者和后者见doc。
如果您想了解为什么您想要使用dequeueReusableCellWithIdentifier:forIndexPath:
请查看此问答 。
我认为这个错误是关于注册你的笔尖或类的标识符。
所以你可以保留你在tableView:cellForRowAtIndexPath函数中所做的事情,只需将下面的代码添加到你的viewDidLoad中:
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];
这对我有用。 希望它可以帮助。
虽然这个问题相当古老,但还有另一种可能性:如果您正在使用Storyboard,则只需在Storyboard中设置CellIdentifier即可。
因此,如果您的CellIdentifier是“单元格”,只需设置“标识符”属性:
确保在完成后清理您的版本。 XCode有时与Storyboard更新有一些问题
我有同样的问题取代
static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell==nil) { cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; }
解决了
这个问题很可能是因为你在storyboard中配置了自定义的UITableViewCell
,但是你不使用storyboard来实例化使用这个UITableViewCell
。 例如,在MainStoryboard中,您有一个名为MyTableViewController
的UITableViewController
子类,并具有一个名为MyTableViewController
并具有标识符ID“MyCell”的自定义动态UITableViewCell
。
如果你像这样创建自定义的UITableViewController
:
MyTableViewController *myTableViewController = [[MyTableViewController alloc] init];
它不会自动注册您的自定义tableviewcell。 您必须手动注册它。
但是如果你使用storyboard来实例化MyTableViewController
,像这样:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; MyTableViewController *myTableViewController = [storyboard instantiateViewControllerWithIdentifier:@"MyTableViewController"];
好的事情发生了! UITableViewController
会自动注册您在故事板中为您定义的自定义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将自动为您创建新的单元格,如果在回收队列中没有可重用的单元格可用。
那你就完成了!
我只是补充一点, Xcode 4.5包含新的dequeueReusableCellWithIdentifier:forIndexPath:
在其默认的模板代码中 – 开发人员希望使用旧的dequeueReusableCellWithIdentifier:
方法。
在您的故事板中,您应该将您的原型单元格的“标识符”设置为与您的CellReuseIdentifier“单元格”相同。 那么你将不会得到这个消息,或者需要调用registerClass:函数。
Swift 2.0解决方案:
您需要进入属性检查器并为您的单元格添加一个名称标识符:
那么你需要使你的标识符和你的出队符一致:
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类参考说:
在出队之前,调用此方法或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)
如果您正在使用自定义静态单元格,只需评论此方法:
//- (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文件加载单元格对象。 如果现有的单元可用于重用,则此方法将调用单元的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"
给你的笔尖名称
我昨天花了几个小时,为什么我的程序生成表崩溃了[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连接起来,如果你想锚定popover到它。
UIPopoverController * popoverController3是在H文件之后的@interface之间直接声明的,
FWIW,当我忘记在故事板中设置单元格标识符时,我得到了同样的错误。 如果这是您的问题,则在故事板中单击表格视图单元格,并在属性编辑器中设置单元格标识符。 确保你在这里设置的单元格标识符与
static NSString *CellIdentifier = @"YourCellIdenifier";
我有同样的问题,是有同样的错误,对我来说,它的工作是这样的:
[self.tableView registerNib:[UINib nibWithNibName:CELL_NIB_HERE bundle: nil] forCellReuseIdentifier:CELL_IDENTIFIER_HERE];
也许这对别人是有用的。
我在Storyboard中正确设置了一切,并做了一个干净的构建,但不断收到错误“ 必须为标识符注册一个笔尖或类,或者在故事板中连接一个原型单元格 ”
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];
纠正错误,但我仍然在亏损。 我没有使用“自定义单元格”,只是一个嵌入tableview的视图。 我已经宣布视图控制器作为委托和数据源,并确保单元格标识符在文件中匹配。 这里发生了什么?
使用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 }
对某些人来说,这可能看起来很愚蠢,但却让我感到害怕。 我得到这个错误,我的问题是,我试图使用静态单元格,但动态地添加更多的东西。 如果你调用这个方法,你的单元需要成为动态的原型。 选择故事板中的单元格,在属性检查器下面,首先是“内容”,您应该选择不是静态的动态原型。
只是一个补充的答案:可能有一段时间,你设置所有的事情正确的,但你可能会不小心添加一些其他的用户界面在你.xib
,就像一个UIButton
: 只需删除额外的用户界面,它的作品。
确保故事板中单元格的CellIdentifier ==标识符都是相同的。 希望这对你有用
在我的情况下,当我调用deselectRowAtIndexPath:
时发生崩溃deselectRowAtIndexPath:
该行是[tableView deselectRowAtIndexPath:indexPath animated:YES];
将其更改为[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
解决我的问题!
希望这有助于任何人
在Swift中这个问题可以通过在你的代码中添加下面的代码来解决
viewDidLoad中
方法。
tableView.registerClass(UITableViewCell.classForKeyedArchiver(), forCellReuseIdentifier: "your_reuse_identifier")