2011-11-04 196 views
2

我正在尋找一種方法來唯一標識UITableViewCells的實例,即使它們已經通過DequeueReusableCell(string identifier)再循環(出列)後 - 沒有子類化或使用容器對象。UITableViewCell唯一標識符?

所以基本上,當我創建一個新的單元格時,我想使用這個單元格的唯一標識符作爲在字典中存儲另一個相關對象的鍵。之後,當細胞被回收/出列時,我想閱讀字典中的相關反對詞。 我完全意識到再循環單元可以放置在表中的任何索引路徑處,並且可能(很可能)包含比以前更多的其他數據 - 另一個對象實際上與單元實例相關,而不是索引路徑。

必須避免與物體的鬆動關係。獲得的ID必須不惜一切代價與創建單元格時使用的相同。

這是通過生成一個隨機數並將其作爲單元格的標記存儲來實現的。但是,這些標籤可能會發生碰撞(當兩次產生相同的隨機數時),我只想實現避免碰撞作爲最後的手段。所以我正在尋找更好的方法。

我看過ClassHandle,HandleSuperHandle屬性。唯一一個在排隊中保持一致的人似乎是ClassHandle。

爲此目的使用ClassHandle屬性是否安全?如果不是,還有什麼其他選擇?

+0

出於好奇,是否有一個特別的原因,你不想子類UITableViewCell?這樣做很可能會使應用程序複雜得多,因爲您可以直接在單元中存儲任何類型的引用,而無需擔心。我們創建了一個非常簡單的繼承類,它有一個非常靈活的Object標籤,並且適用於我們迄今爲止所面對的每種場景。 –

+0

Android和iOS版本的應用程序當前都使用字典爲每個單元存儲一個附加對象(如果需要)。我只想保持一致。 – riha

回答

2

您可以創建自己的單調遞增數:

static int monotonicNumber; 

,然後設置標籤:

cell.Tag = System.Threading.Interlocked.Increment (ref monotonicNumber); 

注意Environment.TickCount不能保證是唯一的,你可以得到如果您連續快速獲取它,則相同的滴答計數。我知道,因爲它發生在我身上。

+0

1)爲什麼要靜態?請解釋。 2)簡單地++數字可以嗎? AFAIK,只有UI線程纔會執行UI代碼。 – riha

+0

1)爲什麼不呢?它實際上取決於您的代碼,如果您知道跨類的多個實例不需要唯一的ID,則也可以使用實例字段。由於我不知道你是否需要,我選擇了安全選項:靜態。 2)是的,如果它只會被UI線程使用,你可以使用增量運算符++。 –

+0

感謝您的澄清 – riha

1

你也可以使用GUID:http://msdn.microsoft.com/en-us/library/system.guid.newguid.aspx

這些都是標準的,被證明始終是唯一的,對於.NET的ID。這些可以在Windows上運行,也可以在任何地方運行。

我假設Tag屬性是一個對象,你可以將它存儲在那裏(但可能是一個int知道蘋果)。如果沒有,您可以繼承UITableViewCell的子類以添加Guid類型的屬性。

+0

標記是一個int(不幸) – riha

+0

你應該爲你的目的子類UITableViewCell的聲音。他們仍然會使用DequeueReuseableCell正確出來,您可以投射到您的新類型。 – jonathanpeppers

2

除了喬納森辣椒的答案,這是在網上無數的例子使用一個相當普遍的技術:

每當你在GetCell方法創建一個新的細胞,將細胞的Tag使用

cell.Tag = Environment.TickCount; 

如果您有自定義單元格對象,這將特別有用。你的細胞然後可以在您的數據源類使用字典進行跟蹤,例如:

Dictionary<int, your_cell_type> cells = ... 

如果您需要跟蹤一些細胞特異性,您可以使用Tag查一查你的字典對象。

+0

看起來很有希望,我會試一試並回報。 – riha

+0

這是原始的文章,我從這個想法得到:http://www.infoq.com/articles/monotouch-custom-tables – Ryan

+0

如果你採取這種方法,你必須非常小心地刪除對單元格的引用字典對象,以便在字典中積累一堆單元時不會出現內存泄漏。 –