UITableViewCell cellForRowAtIndexPath calling large number of rows when first scrolling
I have been working on a problem relating to UITableView and cellForRowAtIndexPath.
I want to give the user the ability to have a very large number of rows much like a large list of email on iPhone. I discovered this problem when I began to create a class that would queue and dequeue groups of records from the database, as needed, in order to conserve memory. I found that when my UITableViewController loads, it then calls cellForRowAtIndexPath for the typical first 10 indexes (0 through 9). The problem ocurrs when I either click my mouse on the simulator's black outer surface area or I attempt to scroll down on the UITableView using an upward gesture. At this point, cellForRowAtIndexPath gets called for all remaining indexes. This happens even if there are 1000+ cells. I have attempted recreating a VERY SIMPLE project with only 100 indexes (nothing fancy). It does exactly the same thing.. as soon as I scroll, it calls cellForRowAtIndexPath from positions 10 to 99.
Is this the normal behavior of a UITableView? Does anyone anyone have any ideas why it is inefficiently calling all rows?
I will say that once this initial pass occurs, it seems like it begins to work correctly. I am really puzzled by this because it makes it almost impossible to create a class for queuing and de-queuing records as need.
Here is the code on my much simpler sample project:
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 100;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
printf("RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = %d\n", indexPath.row);
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = @"Example Text";
return cell;
}
Console:
...... Initial Load of View ......
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 0
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 1
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 2
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 3
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 4
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 5
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 6
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 7
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 8
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 9
...... First Scroll Gesture ......
ootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 11
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 12
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 13
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 14
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 15
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 16
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 17
. . I removed a few here to shorten it up . .
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 97
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 98
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 99
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 10
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 11
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 12
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 13
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 14
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 15
RootViewController, -tableView:cellForRowAtIndexPath; // indexPath.row = 16
(gdb)
Thanks for your help.
Eric
Edit (subsequent day) --> Today I thought to try a real device instead of my simulator开发者_运维知识库. My iPhone 3GS does not reproduce this strange behavior. I believe there might be something wrong with the simulator on my machine. I plan to try another MAC when time permits.
The cause of this problem was an application I have installed on my Mac called Cinch.
Cinch is a window management application that adds a windows 'snap' feature to Mac OS. The program works great otherwise. Whenever I am working with cellForRowAtIndex path, I'll just have to remember to disable Cinch.
Sadly, I had to reload my entire computer to figure this out! Hope this is helpful to anyone else experiencing this weird functionality.
just in case that some has the same strange problem and has no program like chinch installed: the same behaviour is occuring if you don't use a really individual cellidentifier.. if you just use the standard-identifier out of apple's examples, then it won't work.
everytime you slide your tableview there are entries spinning around. you have to make your cell identifiers unique for every cell. eg.:
NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%d", indexPath.row];
it took me a while to figure this out.. so if somebody finds this thread like me while looking for "uitableview uitableviewcell strange behaviour row switch content on touch slide" he could check this possible error source..
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
}
user this nil for reuseidentifier so it work correctly
精彩评论