at first,i delete one cell in tableView,then i want to add another new cell in the t开发者_StackOverflowableView,but the new cell is not new,it is just the cell which i delete. i know what dequeueReusableCellWithIdentifier means.i think when delete one cell,the cache in dequeueReusableCellWithIdentifier is also deleted.why not?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"table reload");
PDFModel* tempmodel=[PDFArray objectAtIndex:indexPath.row];
NSString * CellIdentifier=tempmodel.PDFName;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSLog(@"cell %x",cell);
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
//custom the cell
cell.text=...
}
return cell;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle==UITableViewCellEditingStyleDelete)
{
[PDFArray removeObjectAtIndex:indexPath.row];
NSMutableArray* array=[[NSMutableArray alloc] init];
[array addObject:indexPath];
[self.tableView deleteRowsAtIndexPaths:array withRowAnimation:UITableViewRowAnimationRight];
}
}
There's no reason to delete the UITableViewCell since it can be reused. That cell won't be displayed until it is processed again by cellForRowAtIndexPath
, so it won't show up with the old data. The laid-out cell, though -- the view and all of its subviews -- can be reused after new data replaces the old data.
Think of it like each cell is a whiteboard (dry erase board) where it's cut down to a certain size and all of the basic information areas are etched into the surface: a place for some text, another area for a number, a special space for drawing a picture, etc. In tableView:cellForRowAtIndexPath:
when you check whether the cell == nil
, you're trying to find out if there are any already-etched whiteboards available that you can erase and write the new information on with your dry erase marker. If there aren't then it cuts out and etches a brand new board to write information on, but if there is one that can be erased then it just wipes off the old information with an eraser and writes in the new information. As you can imagine, this saves a lot of time.
When a user is scrolling the table what's actually happening is that when one cell (whiteboard) scrolls off the top and is no longer visible, the system erases the data and moves it to the bottom of the stack; it will be the next one to scroll into view. As a result the system only has to create as many whiteboards as can be visible at any one time -- the ones off-screen don't actually exist.
When you delete a cell all you're really doing is telling the table to (a) stop displaying that cell, and (b) setting a flag so the table can use the eraser to wipe off the old data but still reuse the whiteboard.
Creating cells can be very costly in terms of computing power. If a UITableView had to create a new cell every time one came into view while the user was scrolling -- in the analogy, if it had to cut out a new whiteboard and etch all of the areas into it every time one came into view -- the scrolling would be very jerky and look terrible. By reusing cells, replacing just the changing contents, the table can move smoothly as the user interacts with it.
Your question is a bit weird, but I guess you're wondering what the following code does?
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
What the code does, is that it tries to retrieve a cached UITableView cell. This is to reduce memory usage on the iPhone.
Once you delete a cell, you should also remove the data from the datasource (usually an array), e.g.:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle==UITableViewCellEditingStyleDelete)
{
// remove object from array ...
[dataArray removeObjectAtIndex:indexPath.row];
}
}
(Remember: you can only remove items from an NSMutableArray at runtime, not from a NSArray)
If the cell gets redrawn, you will first check which cell needs to be redrawn, then you retrieve the appropriate data from the datasource, this is all done by the UITableViewDataSource delegate methods. You only have to make sure to retrieve the right content from the array and update the cell's content on redraw, e.g. like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
// no cached cell is found, create a new cell ...
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
// add some defaults for cells in the initializer,
// stuff that's done here should be important for
// all displayed cells, for example background image.
}
// update the cell's content, e.g.: - it will only display content that's currently in the array, deleted objects shouldn't exist in the array at this point
NSString *title = [dataArray objectAtIndex:indexPath.row];
[cell.textLabel setText:title];
return cell;
}
I think You can use
NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%d",indexPath.row];
instead of
NSString * CellIdentifier=tempmodel.PDFName;
please replace it & check it. I think it's helpful to you.
You seem confused by the difference between deleting a cell (an objective-c UI object) and the data it displays.
When you allow a user to delete a cell in the user interface you need to delete the corresponding data from your data model
The implementation of UITableView is highly optimized in iOS and it caches cells (UI objects) to improve performance. You don't really need to be concerned about this as your table will be optimally loaded and displayed based on your data.
In tableView:cellForRowAtIndexPath:
you do the following:
Attempt to dequeue a cell instance. This takes advantage of caching done by UITableView
If dequeue does not return a cell, create a new one.
Once you have a cell, configure it with the appropriate data from your data model
When a user chooses a delete action from a cell, delete the data from your data model. optionally, you can animate removing the cell from the table or simply reload the whole table.
The specifics of #4 depend on the user interface you want and how you've configured your data model.
The Apple docs are pretty good about explaining this.
http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/TableView_iPhone/AboutTableViewsiPhone/AboutTableViewsiPhone.html
精彩评论