xcode 继续从 dequeueReusableCellWithIdentifier 获取 nil?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9797821/
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
Keep getting nil from dequeueReusableCellWithIdentifier?
提问by Fengzhong Li
I've created a prototype cell with identifier "mainViewTableCell" in storyboard file and connected the main table view with a custom controller class named "NTTableViewController". I've implemented function "tableView cellForRowAtIndexPath" in NTTableViewController.m as follows:
我在故事板文件中创建了一个标识符为“mainViewTableCell”的原型单元格,并将主表视图与一个名为“NTTableViewController”的自定义控制器类连接起来。我在 NTTableViewController.m 中实现了函数“tableView cellForRowAtIndexPath”,如下所示:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString* MAINVIEW_CELLIDENTIFIER = @"mainViewTableCell";
UITableViewCell *newCell = [tableView dequeueReusableCellWithIdentifier: MAINVIEW_CELLIDENTIFIER];
if (newCell == nil) {
newCell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: MAINVIEW_CELLIDENTIFIER];
[newCell autorelease];
newCell.selectionStyle = UITableViewCellSelectionStyleNone;
}
NTContactItem* currentItem = [self.contactItemContainer objectInContainerAtIndex: indexPath.row];
NSString* firstName = currentItem.firstName;
NSString* lastName = currentItem.lastName;
NSString* fullName = [firstName stringByAppendingFormat: lastName];
[newCell.textLabel setText: fullName];
[newCell.detailTextLabel setText: currentItem.mobilePhone];
return newCell;
}
But i keeping getting nil from dequeueReusableCellWithIdentifier and have to create a new instance of cell every time.
但是我一直从 dequeueReusableCellWithIdentifier 获取 nil 并且每次都必须创建一个新的单元格实例。
Then, what is wrong?
那么,有什么问题呢?
The code : project
代码:项目
Thank you all in advance.
谢谢大家。
回答by Firoze Lafeer
With storyboards and tableviews that have prototype cells, [tableView dequeueReusableCellWithIdentifier:]
should not return nil. Even if this is the very first cell, and there are no cells already in the reuse queue, the tableview will create a new instance of your prototype cell and return that.
对于具有原型单元格的故事板和表格视图,[tableView dequeueReusableCellWithIdentifier:]
不应返回 nil。即使这是第一个单元格,并且重用队列中已经没有单元格,tableview 也会创建一个原型单元格的新实例并返回它。
In your case, the problem was something totally different (I downloaded your project because I was really curious).
在您的情况下,问题完全不同(我下载了您的项目,因为我真的很好奇)。
In your application's delegate in your application:didFinishLaunchingWithOptions:
method, you are re-initializing this tableviewcontroller. When you call [masterController init]
, this calls [super init]
, which in turn calls [UITableViewController initWithStyle:]
.
在您的application:didFinishLaunchingWithOptions:
方法中的应用程序委托中,您正在重新初始化此 tableviewcontroller。当您调用时[masterController init]
, this 会调用[super init]
,而后者又会调用[UITableViewController initWithStyle:]
。
That causes the controller to create a new UITableView, which is different from the one in your storyboard. That new UITableView has no prototype cells, and so that's why dequeueReusableCellWithIdentifier:
is returning nil.
这会导致控制器创建一个新的 UITableView,它与故事板中的不同。那个新的 UITableView 没有原型单元格,所以这dequeueReusableCellWithIdentifier:
就是返回 nil的原因。
The lesson of course is to not re-initialize an Objective-C object that has already been initialized. When your table view controller is loaded from the storyboard, the loading mechanism will initialize it with initWithCoder:
. So if you need to do some custom initialization work (like setting up that NSMutableArray in your case), then just override initWithCoder:
and/or awakeFromNib
.
教训当然是不要重新初始化已经初始化的Objective-C 对象。当您的表视图控制器从故事板加载时,加载机制将使用initWithCoder:
. 因此,如果您需要进行一些自定义初始化工作(例如在您的情况下设置该 NSMutableArray),那么只需覆盖initWithCoder:
和/或awakeFromNib
.
You can override these methods as needed, but do notcall them yourself. Both initWithCoder:
and awakeFromNib
will be called by the Storyboard/nib loading mechanism.
您可以根据需要覆盖这些方法,但不要自己调用它们。双方initWithCoder:
并awakeFromNib
会被情节提要/笔尖加载机制被调用。
If everything is correct, you do not need to create cells programmatically here. This bit of code should not be needed:
如果一切正常,则无需在此处以编程方式创建单元格。应该不需要这段代码:
// This bit is unnecessary with storyboards:
if (newCell == nil) {
newCell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: MAINVIEW_CELLIDENTIFIER];
[newCell autorelease];
newCell.selectionStyle = UITableViewCellSelectionStyleNone;
}
Hope that helps.
希望有帮助。
回答by canhazbits
After reading @Firoze's answer I fixed my problem that had been haunting me for days.. and found another solution. I know the question has already been answered but this may help someone out.
阅读@Firoze 的回答后,我解决了困扰我好几天的问题……并找到了另一个解决方案。我知道这个问题已经得到了回答,但这可能会对某人有所帮助。
In my case I had done some refactoring (extracted a new TableViewController), and afterwards I was getting nil cells returned from dequeueReusableCellWithIdentifier
.
就我而言,我进行了一些重构(提取了一个新的 TableViewController),然后我从dequeueReusableCellWithIdentifier
.
The fix for me was to do this instead of calling alloc/init
on my ViewController in didSelectRowAtIndexPath
:
对我来说,解决方法是执行此操作,而不是在以下位置调用alloc/init
我的 ViewController didSelectRowAtIndexPath
:
UIStoryboard* sb = [UIStoryboard storyboardWithName:@"MainStoryboard"
bundle:nil];
MyTableViewController* controller = [sb instantiateViewControllerWithIdentifier:
@"MyTableViewController"];
(Then I call [self.navigationController pushViewController:controller animated:YES];
- not the cleanest way perhaps but it works)
(然后我打电话[self.navigationController pushViewController:controller animated:YES];
- 也许不是最干净的方式,但它有效)
回答by TomCobo
Just in case it could help somebody in the future... In my case I forgot to change in TableView (Storyboard) Content from "Static cells" to "Dynamic Prototypes".
以防万一它可以在未来帮助某人......在我的情况下,我忘记将 TableView(故事板)内容从“静态单元格”更改为“动态原型”。
回答by fbernardo
Table cells only become reusable when they are hidden, so you should only have the number of cells you're currently displaying in memory. How many cells are you displaying, and how many are alloc'ed?
表格单元格只有在隐藏时才可重用,因此您应该只拥有当前在内存中显示的单元格数量。您显示了多少个单元格,分配了多少个单元格?
回答by SwiftArchitect
Typical cause:
典型原因:
[tableView dequeueReusableCellWithIdentifier: @"id"];
does not match Xcode > Attribute Inspector > Table View Cell> Identifier> id
[tableView dequeueReusableCellWithIdentifier: @"id"];
不匹配 Xcode > Attribute Inspector > Table View Cell> Identifier> id