继续从dequeueReusableCellWithIdentifier获取nil? [英] Keep getting nil from dequeueReusableCellWithIdentifier?

查看:806
本文介绍了继续从dequeueReusableCellWithIdentifier获取nil?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在storyboard文件中创建了一个标识符为mainViewTableCell的原型单元格,并将主表视图与名为NTTableViewController的自定义控制器类连接起来。
我在NTTableViewController.m中实现了函数tableView cellForRowAtIndexPath,如下所示:

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:


- (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;
}

但我一直从dequeueReusableCellWithIdentifier获取nil并且必须创建一个新的cell实例每次。

But i keeping getting nil from dequeueReusableCellWithIdentifier and have to create a new instance of cell every time.

然后,出了什么问题?

代码:项目

提前谢谢大家。

推荐答案

对于具有原型单元格的故事板和tableviews, [tableView dequeueReusableCellWithIdentifier:] 不应返回nil。即使这是第一个单元格,并且重用队列中已经没有单元格,tableview将创建原型单元格的新实例并返回该实例。

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.

在你的情况下,问题是完全不同的(我下载你的项目,因为我真的很好奇)。

In your case, the problem was something totally different (I downloaded your project because I was really curious).

应用程序中的应用程序委托中:didFinishLaunchingWithOptions:方法,您正在重新初始化此tableviewcontroller。当你调用 [masterController init] 时,这会调用 [super init] ,然后调用 [UITableViewController initWithStyle:]

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:].

这会导致控制器创建一个新的UITableView,它与故事板中的UITableView不同。新的UITableView没有原型单元格,所以 dequeueReusableCellWithIdentifier:返回nil。

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.

当然的教训是不重新初始化已经初始化的Objective-C对象。从故事板加载表视图控制器时,加载机制将使用 initWithCoder:初始化它。因此,如果您需要进行一些自定义初始化工作(比如在您的情况下设置NSMutableArray),那么只需覆盖 initWithCoder:和/或 awakeFromNib

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.

您可以根据需要覆盖这些方法,但不要自己调用它们。两个 initWithCoder: awakeFromNib 将由Storyboard / nib加载机制调用。

You can override these methods as needed, but do not call them yourself. Both initWithCoder: and awakeFromNib will be called by the Storyboard/nib loading mechanism.

如果一切正确,则无需在此以编程方式创建单元格。不需要这段代码:

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;
}

希望有所帮助。

这篇关于继续从dequeueReusableCellWithIdentifier获取nil?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆