2010-10-27 23 views
3

我一直在处理有关UITableView和cellForRowAtIndexPath的问题。UITableViewCell cellForRowAtIndexPath第一次滚动时调用大量的行

我想让用户拥有非常大量的行,就像iPhone上的大量电子邮件列表一样。当我开始创建一个类时,我会发现这个问题,该类会根据需要对数据库中的记录组进行排队和排队,以节省内存。我发现当我的UITableViewController加载时,它会为典型的前10个索引(0到9)调用cellForRowAtIndexPath。当我在模拟器的黑色外表面区域上单击鼠标时出现问题,或尝试使用向上的手势向下滚动UITableView。此时,cellForRowAtIndexPath被所有其余索引调用。即使有1000多个单元,也会发生这种情况。我试图重新创建一个只有100个索引的非常简单的项目(没有什么奇特的)。它完全相同的事情..只要我滚动,它调用cellForRowAtIndexPath从位置10到99.

这是UITableView的正常行为?有没有人有任何想法,为什么它无效地调用所有行?

我会说,一旦这个初始传递发生,它似乎开始正常工作。我对此感到十分困惑,因为它根本不可能根据需要创建排队和出队记录的类。

这里是我的简单得多示例项目代码:

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

控制台:

...... 查看 的初始加载......

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

...... 首先滚动手势 ......

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

。 。 我在这里删除了一些以缩短它 。 。

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)

感谢您的帮助。

埃里克

编辑(次日) - >今天,我想尝试真正的设备,而不是我的模拟器。我的iPhone 3GS不会重现这种奇怪的行为。我相信我的机器上的模拟器可能有问题。我计划在时间允许的情况下尝试另一个MAC。

回答

11

这个问题的原因是我在Mac上安装的应用程序叫做Cinch。

Cinch是一个窗口管理应用程序,它为Mac OS添加了一个Windows'snap'功能。该方案很好,否则。每当我使用cellForRowAtIndex路径时,我只需要记住禁用Cinch。

不幸的是,我不得不重新加载我的整个计算机来解决这个问题!希望这对任何遇到这种奇怪功能的人都有帮助。

+0

感谢你这么多的这个答案。我被困在完全相同的probme上,并使用了Cinch。你为我节省了很多浪费时间。 – CodeFlakes 2011-01-10 11:50:44

+0

你是我的英雄!我从来没有想过这一点。非常感谢。 – Larry 2011-12-09 11:13:09

+0

@geekinit请选择您的答案 – 2011-12-13 19:46:36

1

只是为了防止某些人有相同的奇怪问题,并且没有安装chinch程序:如果您不使用真正单独的cellidentifier,则会发生相同的行为..如果您仅使用标准标识符例子,那么它将无法工作。

每次你滑动你的tableview时都会有条目在旋转。你必须让你的单元格标识符对每个单元格都是唯一的。例如:

NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%d", indexPath.row]; 

我花了一段时间来算出这个..所以,如果有人发现像我这个线程,同时寻找“的UITableView的UITableViewCell上触摸滑动奇怪的行为列交换机的内容”,他可以检查此可能的错误源..

+0

我想你错过了单元重用机制的全部观点。当一个单元格离开屏幕时,它将进入重用队列,因此可以再次使用另一个索引路径。这样,同一个单元对象可以通过'dequeueReusableCellWithIdentifier'用于多行(出于性能原因)。因此,不是实例化很多单元,而是根据需要实例化多个单元,即多个可见单元。如果您给每个单元格一个唯一的重用标识符,则根本不会重用您的单元格。 – albertamg 2011-05-23 20:45:47

+0

嗯...那么请告诉我,我应该如何填充我的细胞数据?我在cellForRowAtIndexPath方法中执行此操作。我为相应的行创建单元格并为数据添加标签。当细胞看不见时,其他细胞被分配并填充数据。如果用户再次向上滚动到第一个单元格,它将从dequeueReusableCellWithIdentifier方法中出列。所以每个单元格重新使用时,再次显示。你会怎么做别的呢?只是一个细胞对象的内容不断变化? – dac 2011-05-23 21:28:07

+0

好吧,我再次测试它..看来,我错了 - 它现在似乎工作。也许我在我的代码中有一些其他问题,它现在已经不存在了。 – dac 2011-05-23 21:37:27

0
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil]; 
    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease]; 
    } 

用户这个零对reuseidentifier所以它正常工作

相关问题