Sachin
Sachin

Reputation: 105

How many cells are present in a single view for a UITableView?

I was asked a question about how many cells are there in a single view of a table view before it begins using its dequeueReusableCellWithIdentifier delegate.

I used the following program but it resets after 12 rows and begins with 1 again.

NSMutableArray *array;

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

static NSString *CellIdentifier = @"Cell";

UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if(cell==nil){
    cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];


    NSString *cellValue = [array objectAtIndex:indexPath.row];

    cell.textLabel.text=cellValue;
}

return cell;

}

-(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
{
    return [array count];
}

And my viewDidLoad

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.


array = [[NSMutableArray alloc]init];

for(int i=1; i<=24 ; i++)
 {   
    NSMutableString *str = [[NSMutableString alloc]initWithString:@"Sachin"];
    NSString *integ = [NSString stringWithFormat:@"%d",i];
    [str appendString:integ];
    [array addObject:str];
 }
}

And my output screenshot at OutputImage

Sorry for the noob question. Just began iOS programming.

Upvotes: 3

Views: 1986

Answers (3)

Gabriele Petronella
Gabriele Petronella

Reputation: 108101

You should initialize the cell outside the if (cell==nil) block

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

    static NSString *kCellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier];

    if(cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellIdentifier];
    }

    NSString *cellValue = array[indexPath.row];
    cell.textLabel.text = cellValue;
    return cell;
}

EDIT

Ok I'll try to answer to your original question. Short answer is: it depends.

Table Views, in short

First, here's how table views work.

At every data source call dequeueReusableCellWithIdentifier. What this method does is to look into a cache and return a cell with that identifier if found, otherwise it will return nil. Every time a cell goes beyond the tableview's bounds (i.e. it disappears from the screen) it will be put in the aforementioned cache.

When does dequeueReusableCellWithIdentifier: kick in?

So, back to your question

how many cells are there in a single view of a table view before it begins using its dequeueReusableCellWithIdentifier

Well, strictly speaking, it always uses it. Just sometimes (typically at the very beginning) it returns nil, i.e. a cache miss, so your implementation handles this case by allocating a new cell So the question becomes: when will dequeueReusableCellWithIdentifier: start to hit the cache?

Again, it depends. In case of a table view with a single identifier, it's very likely that the cache will be hit as soon as the first cell disappears from the screen (and therefore is inserted in cache). So if you are currently displaying 12 cells, and you start scrolling, the 13th will be probably allocated from scratch as the 1st is still visible, but the 14th will probably reuse the 1st one, which in the meanwhile has gone offscreen.

Let's complicate this stuff

But this is a very simple case. Theoretically you could never hit the cache. Suppose that you do something very weird (and not-so-smart) and you dynamically define an identifier for each cell in the table. In such case no cells would be reused, leading to a ridiculous performance drop in scrolling.

Conclusions

Bottom line, there's no single shot answer to your question. It depends on the viewport you're working with, on the cells height, on the number of different cell identifiers, and so on. Moreover we don't know exactly how the cache is implemented, so there may be other factors that we cannot take into account.

Hope that answers your curiosity.

One more thing, on iOS 6

FYI, in iOS 6 a new method for dequeuing has been introduced: dequeueReusableCellWithIdentifier:forIndexPath

The main difference with this method is that it never returns nil. On a cache miss, it automatically creates a new one based on the class or nib file you previously registered.

In order to register a nib/class you can either defined a prototype cell in Interface Builder (the common way to go) or programmatically do it by calling registerNib:forCellReuseIdentifier: or registerClass:forCellReuseIdentifier:.

If no nib/class with the required identifier is found, an exception will be raised.

Upvotes: 5

zbMax
zbMax

Reputation: 2818

what i was doing using the above program was trying to find out how many cells are created before cell reuse begins.

When you table reload datas (i.e. from an explicit call or after a viewDidAppear) the table reuse the available cells at this moment. So if you have an empty table view, it first fills the table with NEW cells and once the table is created and you begin to scroll, it reuses the cells.

Upvotes: 2

zbMax
zbMax

Reputation: 2818

Because you use dequeueReusableCellWithIdentifier, when you scroll your view, then top cell will go at the bottom. So set your text label out of your condition where you test if you cell is nill

Upvotes: 0

Related Questions