我有一個帶有實例變量ImageView的類A.目前我使用setTag()從ImageView返回到A類的實例。可以提供循環嗎?我也聽說過提及弱引用。獲取ImageView的父類A的最佳方式是什麼?從成員imageview跟蹤父類
我的使用場景是我在屏幕上拖動ImageView,並且需要訪問A類來獲取有關被拖動的ImageView的信息。
我有一個帶有實例變量ImageView的類A.目前我使用setTag()從ImageView返回到A類的實例。可以提供循環嗎?我也聽說過提及弱引用。獲取ImageView的父類A的最佳方式是什麼?從成員imageview跟蹤父類
我的使用場景是我在屏幕上拖動ImageView,並且需要訪問A類來獲取有關被拖動的ImageView的信息。
我相信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的GC將有問題的檢測這種依賴,安卓是行不通的,因爲它的工作原理。 繼續並使用View.setTag(如果它適合您的目的)。
我在網上尋找確認,settag是一個弱引用。似乎無法找到它呢? – prostock 2012-02-08 18:30:07
查看源代碼: protected Object mTag; public void setTag(final Object tag){ mTag = tag; } – 2012-02-08 20:01:45
setTag與WeakReferences無關。但是,如果這是您想要實現的,則可以將WeakReference放入標記中。這就是說,請確定你明白WeakReference實際上首先會給你帶來什麼。 – 2012-02-13 22:19:18
擺脫循環引用的最好辦法是使實例變量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);
...
}
Java中的循環引用對GC來說不是問題。這不是一個問題,因爲有一個叫做「可達性」的概念。
您可以將對象引用視爲有向圖,其中節點是對象,邊是對象引用。圖中有一組稱爲「根節點」的節點 - 這些(大致)是可以直接訪問vm中的某個線程的對象。例如堆棧中的任何函數調用中的局部變量,類中的靜態字段等。
執行垃圾回收時,虛擬機以這些根節點開始,並將它們標記爲「正在使用中」。然後,對於從這些正在使用的節點中引出的每個邊(即,對於從正在使用的對象引用的每個對象),它還標記爲正在使用中,等等,直到沒有剩下任何東西標記。然後,沒有標記爲「正在使用」的任何對象,它知道它可以安全地垃圾收集。
現在,讓我們說,例如,你在某些方法是,你有下面的代碼:
a = new A();
a.b = b;
b = new B();
b.a = a
你現在有A和B之間的循環引用。而這兩個對象都是根集的一部分,因爲它們是堆棧中方法調用的局部變量。
然後,當您退出該方法時,a和b將不再是根集的一部分。只要你沒有在其他地方提及它們,就沒有其他地方可以提及a或b。
所以,現在,您的對象參考圖將有一個包含a和b的圖的一個小斷開部分。他們兩人仍然有彼此的引用,但沒有別的可以參考他們。由於它們無法從根集訪問,因此GC知道它們沒有被使用,並且可以垃圾收集它們 - 儘管它們之間有相互引用。
(注意,這是垃圾收集的略微簡化的描述,但它仍然是它是如何工作的有益/合理的心智模式)
那麼簡單的答案是 - 「是的,你有一個循環引用但這不是問題,因爲一旦兩個對象都不再可以重新收斂,就會收集兩個對象「
爲什麼不使用自己的HashSet來跟蹤您的引用(ImageView的ID - > ClassA實例) ? –
Olegas
2012-02-07 08:13:47