謹防
以下的答案必須解決的具體實施,而不是設計。使用NSFetchedResultsController
的樣板代碼將首先防止此錯誤發生。 (Apple documentation)。不惜一切代價,避免操縱一旦通過cellForRowAtIndexPath
返回的單元格:你做不是擁有它。
1.重複使用的細胞不會被緩存
中特別令人擔憂的是這一行:
[self.arrayHistory objectAtIndex:indexPath.row]
與其說是因爲該特定實例的,而是因爲它使我認爲你在這個課程的其他地方做假設:通過dequeueReusableCellWithIdentifier
檢索的UITableViewCell
不過是一個瞬態對象,純粹用於UITableView
顯示。
的非常相同的小區的實例將具有多個indexPath隨時間:這樣的細胞可能不被緩存或在進一步的日期操縱。一旦作爲cellForRowAtIndexPath
的最後一條語句返回,可能會再次訪問而不是,無論是通過某種外部指針通過某種異步方法保留。始終將通過dequeueReusableCellWithIdentifier
獲取的緩存表視圖的索引路徑視爲陳舊。
做不是修改一次返回的單元格的內容。按照以下Losiowaty所述的正確設計。
對於更好的判斷,如果您必須修改已經返回到表視圖的單元格的內容,那麼您必須爲此使用一個持久單元格,例如使用字典UITableViewCell
。除非該標識符專用於該單元,否則您不得在此類單元上調用dequeueReusableCellWithIdentifier
;而對於大型數據集而言,高度的內存效率低下,這將保證單元不被重新使用。
2.不要猜tableview
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
cellHistory = [self.notificationTableView // etc.
正確的邏輯UITableViewDataSource
cellForRowAtIndexPath
是使用傳遞給你的參數:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
cellHistory = [tableView // etc.
3 。再用乾淨的再生細胞
假設你已經掌握了使用dequeueReusableCellWithIdentifier
的回收副作用,並確保你不交叉授粉不同類型的細胞,你可能要cleanup您的重用單元(信貸Timur Bernikowich對他的評論):
func prepareForReuse() {
super.prepareForReuse()
// reset attributes of the cell that are not related to content
}
4.內省第一
總是比較喜歡,我做錯了什麼到它曾經工作在以前的操作系統。雖然第二個命題通常是正確的,但總的來說,歷史可以讓你思考如何在天堂裏工作。
恰恰相反,我通常把這些情況作爲一個確定的信號,我正在做一些可怕的錯誤,我只是幸運地穿過了裂縫。
5.尊重命名約定
雖然我欣賞你塊通過在所述方法中
- (void)setLinksForSubstrings:(NSArray*)string withLinkHandler:(void(^)(FRHyperLabel *label, NSString *substring))handler {}
我有點由Details
對象或userName
的性質揭去,更不用說在[self userNameTapped:[[[[
中的4個括號。如果我被拋棄,其他工程師在第一次接觸到您的代碼時會有機會。
從上下文中,我不能推導出什麼是變量,常量,靜態,實例屬性等。很可能你的單元格在這個層次上被混淆了(你可能會重複使用你認爲是當地人或基於堆棧的值,但不是)。
我可以建議使用typedef
作爲塊,採用大小寫一致性,避免嵌套[
太深。花了不小的努力將代碼與樣板UITableView
代碼進行比較,只是爲了修剪噪音。
請提供更多代碼,如何將數據設置到您的單元格中。 –
我已經更新了上面的代碼。 – Nishan29
您的細胞正在被重複使用。基本的iOS設計知識。大量的例子在線 – soulshined