2012-01-28 3 views
6

클래스 A에 인스턴스 변수 ImageView가 있습니다. 현재 setTag()를 사용하여 ImageView에서 클래스 A의 인스턴스로 되돌아갑니다. 현재 순환 루프가 있습니까? 나는 또한 약한 언급에 대한 언급을 들었다. ImageView의 부모 Class A를 사용하는 가장 좋은 방법은 무엇입니까?회원 이미지 뷰에서 부모 클래스를 추적합니다

내 사용 시나리오는 화면 주위로 ImageView를 드래그하고 ImageView에 대한 정보를 보려면 A 클래스에 액세스해야합니다. 이것은 당신이 명시 적으로 전달하는 경우 A의 생성자에서 변수를 초기화 할 수 강제

private final ImageView myImageView; 

:

+0

jusr가 자신의 HashSet 를 사용하여 참조 (ImageView -> ClassA 인스턴스의 ID) ? – Olegas

답변

3

Dalvik VM에는 순환 참조를 감지하는 데 문제가 없다고 생각합니다.

Circular References in Java 만 매우 순진 구현이 원형 참조에 문제가있는 것 :

다음은이에 대해 설명 Q/A입니다.

관련 개체에 대한 참조를 보유하려면 setTag를 사용합니다. 또한 View에서 setTag/getTag를 사용하는 것은 Android 샘플 에서조차 발견되는 Android에서 다양한 최적화를 달성하기위한 표준 및 권장 접근 방식입니다. 일부 참조 : 안드로이드의 GC는 종속성을 감지하는 문제를했을 경우 작동으로

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

Android Custom Listview

, 안드로이드가 작동하지 않을 것입니다. 목적에 맞는 경우 View.setTag를 사용하십시오.

+0

나는 settag가 약한 참조임을 웹에서 확인하고 있었다. 그래도 그것을 찾을 수 없을 것 같은가요? – prostock

+0

보기의 학습 소스 코드 : 보호 된 개체 mTag; public void setTag (최종 개체 태그) { mTag = tag; } –

+0

set 태그는 WeakReferences와 아무 관련이 없습니다. 그러나 태그에 WeakReference를 넣을 수 있습니다. 즉, WeakReference가 실제로 무엇을 먼저 얻었는지 이해해야합니다. –

0

순환 참조를 제거하는 가장 좋은 방법은 최종 변수에 인스턴스 변수를 확인하는 것입니다 새 호출에서 ImageView에 대한 참조를 사용하면 순환 참조의 가능성을 피할 수 있습니다.

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

자바의 순환 참조는 GC에서 문제가되지 않습니다. 이는 "도달 가능성"이라는 개념 때문에 문제가되지 않습니다.

객체 참조는 노드가 객체이고 에지가 객체 참조 인 유향 그래프로 생각할 수 있습니다. 그래프에는 "루트 노드"라고하는 노드 집합이 있습니다.이 노드는 VM의 일부 스레드가 직접 액세스 할 수있는 개체입니다. 스택상의 함수 호출에서 로컬 변수, 클래스의 정적 필드 등이 있습니다.

가비지 수집을 수행 할 때 VM은 이러한 루트 노드로 시작하여 "사용 중"으로 표시합니다. 그런 다음이 사용 중 노드에서 나오는 각 에지 (즉, 사용중인 객체에서 참조되는 각 객체)에 대해 사용 중이라는 표시가있는 등 아무 것도 남지 않을 때까지 계속 표시됩니다 표. 그런 다음 "사용 중"으로 표시되지 않은 모든 개체는 안전하게 가비지 수집 할 수 있음을 알고 있습니다.

이제, 당신은 몇 가지 방법에있어, 예를 들어 가정 해 봅시다, 다음과 같은 코드가 있습니다

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

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

는 이제 a와 b 사이에 순환 참조가 있습니다. 그리고이 두 객체는 ​​스택에있는 메소드 호출의 로컬 변수이기 때문에 루트 집합의 일부입니다.

그런 다음 해당 방법을 종료하면 a와 b는 더 이상 루트 집합의 일부가 아닙니다. 그리고 당신이 다른 곳에서 그곳에 대한 언급을하지 않는 한, a 나 b에 대한 언급이있는 것은 없습니다.

이제 개체 참조 그래프에는 a 및 b가 포함 된 그래프의 일부 연결이 끊어졌습니다. 둘 다 여전히 서로에 대한 참조를 가지고 있지만 그 외에는 참조가 없습니다. 루트 집합에서 도달 할 수 없으므로 GC는 사용되지 않고 가비지 수집을 할 수 있음을 알고 있습니다. 서로 참조 할 수 있습니다.

(이 가비지 컬렉션의 다소 단순화 된 설명이 있습니다,하지만 여전히 작동 방법에 대한 유용한/합리적인 정신 모델) 그래서 짧은 대답은

- "예, 순환 참조가 그러나 이것은 문제가되지 않습니다. 두 객체가 더 이상 도달 할 수 없게되면 모두 수집 될 것이기 때문입니다. "

관련 문제