Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
468 views
in Technique[技术] by (71.8m points)

objective c - Keep getting nil from dequeueReusableCellWithIdentifier?

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

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

Then, what is wrong?

The code : project

Thank you all in advance.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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).

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

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.

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.

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

Hope that helps.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...