2012-01-28 51 views
6

我有一個帶有實例變量ImageView的類A.目前我使用setTag()從ImageView返回到A類的實例。可以提供循環嗎?我也聽說過提及弱引用。獲取ImageView的父類A的最佳方式是什麼?從成員imageview跟蹤父類

我的使用場景是我在屏幕上拖動ImageView,並且需要訪問A類來獲取有關被拖動的ImageView的信息。

+0

爲什麼不使用自己的HashSet 來跟蹤您的引用(ImageView的ID - > ClassA實例) ? – Olegas 2012-02-07 08:13:47

回答

3

我相信Dalvik VM在檢測循環引用時沒有問題。

這裏的Q/A討論這件事:Circular References in Java

只有一個非常幼稚的實施將有圓形 引用的一個問題。

我會用setTag來保存ref到相關的對象。另外,在View上使用setTag/getTag是標準和推薦的方法,可以在Android上實現各種優化,甚至可以在Android示例中找到。 一些參考:

http://www.vogella.de/articles/AndroidListView/article.html#ownadapter_viewHolder

Android Custom Listview

如果Android的GC將有問題的檢測這種依賴,安卓是行不通的,因爲它的工作原理。 繼續並使用View.setTag(如果它適合您的目的)。

+0

我在網上尋找確認,settag是一個弱引用。似乎無法找到它呢? – prostock 2012-02-08 18:30:07

+0

查看源代碼: protected Object mTag; public void setTag(final Object tag){ mTag = tag; } – 2012-02-08 20:01:45

+0

setTag與WeakReferences無關。但是,如果這是您想要實現的,則可以將WeakReference放入標記中。這就是說,請確定你明白WeakReference實際上首先會給你帶來什麼。 – 2012-02-13 22:19:18

0

擺脫循環引用的最好辦法是使實例變量A中的最後一個變量:

private final ImageView myImageView; 

這將迫使你初始化變量A的構造函數如果你明確地傳遞在新的調用中參考ImageView,您將避免循環引用的機會。

public A(ImageView iv, ...) { 
    this.myImageView = iv; 
    ... 
    // associate this instance of A with ImageView? 
    this.imageView.setTag(this); 
    ... 
    } 
1

Java中的循環引用對GC來說不是問題。這不是一個問題,因爲有一個叫做「可達性」的概念。

您可以將對象引用視爲有向圖,其中節點是對象,邊是對象引用。圖中有一組稱爲「根節點」的節點 - 這些(大致)是可以直接訪問vm中的某個線程的對象。例如堆棧中的任何函數調用中的局部變量,類中的靜態字段等。

執行垃圾回收時,虛擬機以這些根節點開始,並將它們標記爲「正在使用中」。然後,對於從這些正在使用的節點中引出的每個邊(即,對於從正在使用的對象引用的每個對象),它還標記爲正在使用中,等等,直到沒有剩下任何東西標記。然後,沒有標記爲「正在使用」的任何對象,它知道它可以安全地垃圾收集。

現在,讓我們說,例如,你在某些方法是,你有下面的代碼:

a = new A(); 
a.b = b; 

b = new B(); 
b.a = a 

你現在有A和B之間的循環引用。而這兩個對象都是根集的一部分,因爲它們是堆棧中方法調用的局部變量。

然後,當您退出該方法時,a和b將不再是根集的一部分。只要你沒有在其他地方提及它們,就沒有其他地方可以提及a或b。

所以,現在,您的對象參考圖將有一個包含a和b的圖的一個小斷開部分。他們兩人仍然有彼此的引用,但沒有別的可以參考他們。由於它們無法從根集訪問,因此GC知道它們沒有被使用,並且可以垃圾收集它們 - 儘管它們之間有相互引用。

(注意,這是垃圾收集的略微簡化的描述,但它仍然是它是如何工作的有益/合理的心智模式)

那麼簡單的答案是 - 「是的,你有一個循環引用但這不是問題,因爲一旦兩個對象都不再可以重新收斂,就會收集兩個對象「