开发者

iPhone table view - problem with indexPath.row

I'm using indexPath.row do determine in which row of my tableview I do something. The title of my cells is containing a number which should be 1 in the first row and 18 in the last row, so I have 18 rows. This works for the first 11 rows, but after that, I have numbers in the title which seem to be generated randomly! Sometimes 16, then 5, then 18, then 12... and so on. What's the problem with it/why does the indexPath.row variable behave like that?

My cellForRowAtIndexPath method:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *MyIdentifier = @"MyIdentifier";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
    [[NSBundle mainBundle] loadNibNamed:@"myCell" owner:self o开发者_如何转开发ptions:nil];
    cell = cell0;
    self.cell0 = nil;
}
UILabel *label;
label = (UILabel *)[cell viewWithTag:1];
label.text = [NSString stringWithFormat:@"Cell %d", indexPath.row];

return cell;  

}

Any more suggestions on how to solve the problem? I didn't get it working until now...

// Update with more code:

Here is how I declare the cell. It is in an XIB file (template "empty XIB") in which I just put the cell from the library in IB.

@interface myViewController : UITableViewController {

    UITableViewCell *cell0;
}

@property (nonatomic, retain) IBOutlet UITableViewCell *cell0;

Then, at the top of the myViewController.m file:

@synthesize cell0;

My cellForRowAtIndexPath method is already posted above. It is equal to the cellForRowAtIndexPath method in the SDK documentation, and in Apple's example, it seems to work.


What are you trying to accomplish with cell0?

cell = cell0;
self.cell0 = nil;

It looks like you're creating a new cell, but somehow deciding to use an old one. The real culprit looks like the code that is loading the cell actually getting assigned anywhere.

Try just this instead:

if (cell == nil) {
    cell = [[NSBundle mainBundle] loadNibNamed:@"myCell" owner:self options:nil];
}

Or perhaps:

if (cell == nil)
{
     // TODO: try to avoid view controller
     UIViewController *vc = [[UIViewController alloc] initWithNibName:@"IndividualContractWithResult" bundle:nil];
     cell = (IndividualContractWithResult_Cell *) vc.view;
     [vc release];
}


To would be easier to answer if you give the code where you create cells for your table view.
It looks that there's a problem with reusing cells - you reuse previously created cells without setting a new value to it.


It sounds like you are not re-using cells but creating new ones when there are cells available. Look at the sample code for dequeueReusableCellWithIdentifier.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell"];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"MyCell"] autorelease];
    }

    cell.text = <your code here>;
    return cell;
}


It would seem that you're incorrectly accessing a property here:

cell = cell0;
self.cell0 = nil;

Assuming that you have an instance variable named cell0, by setting it to nil, you may be releasing it before you're ready to use it.

The proper way to do this is:

cell = self.cell0;
self.cell0 = nil;

This way, if cell0 is declared as retain, you'll automatically get an autoreleased cell0 back, whereas if you reference cell0 directly (no self.), you'll get an unretained reference, which will disappear when self.cell0 = nil is called.

The advantage of using a nib-based cell here is that you can use outlets, rather than tags, to identify subviews. You've done the heavy lifting already, you might want to just add an outlet and subclass UITableViewCell to get access to the label.


You will need to retain and autorelease cell0, otherwise when you set self.cell0 = nil, then cell0 has no known references.

cell = [[cell0 retain] autorelease];
self.cell0 = nil;

You can also do this:

cell = self.cell0;
self.cell0 = nil;

.. Since any retain properties should implement their getters with the retain/autorelease pattern.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜