2010-10-27 95 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所以它正常工作

相關問題