从成员imageview跟踪父类

时间:2012-01-28 18:19:56

标签: java android

我有一个带有实例变量ImageView的A类。目前我使用setTag()从ImageView返回到A类的实例。这是否存在循环循环?我也听说过弱引用。获得ImageView的父类A的最佳方法是什么?

我的使用场景是我在屏幕上拖动ImageView,我需要访问A类以获取有关被拖动的ImageView的信息。

3 个答案:

答案 0 :(得分:3)

我相信Dalvik VM在检测循环引用方面没有问题。

以下是对此进行讨论的问答:Circular References in Java

  

只有非常天真的实现才会出现循环问题   引用。

我会使用setTag来保存引用相关对象的引用。此外,在View上使用setTag / getTag是在Android上实现各种优化的标准和推荐方法,甚至可以在Android示例中找到。 一些参考文献:

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

Android Custom Listview

如果Android的GC在检测此类依赖关系时遇到问题,Android将无法正常工作。 如果适合您的目的,请继续使用View.setTag。

答案 1 :(得分:1)

java中的循环引用不是GC的问题。由于称为“可达性”的概念,这不是问题。

您可以将对象引用视为有向图,其中节点是对象,边是对象引用。图中有一组称为“根节点”的节点 - 这些节点(大致)是vm中某些线程可直接访问的对象。任何函数中的局部变量都会调用堆栈,类中的静态字段等等。

执行垃圾收集时,VM从这些根节点开始,并将它们标记为“正在使用”。然后,对于从这些正在使用的节点中引出的每个边缘(即,对于从使用中对象引用的每个对象),它也标记为在使用中,依此类推,直到没有任何东西留给标记。然后,任何未标记为“正在使用”的对象,它知道它可以安全地进行垃圾收集。

现在,让我们假设您使用某种方法,并且您拥有以下代码:

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

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

您现在在a和b之间有一个循环引用。这两个对象都是根集的一部分,因为它们是堆栈中方法调用中的局部变量。

然后,当您退出该方法时,a和b将不再是根集的一部分。只要你没有在其他地方引用它们,就没有别的东西可以引用a或b。

现在,您的对象引用图将包含一个包含a和b的图的一些断开连接的部分。他们俩仍然互相引用,但没有别的东西可以引用它们。由于它们无法从根集中访问,因此GC知道它们没有被使用并且可以垃圾收集它们 - 即使它们彼此有引用。

(请注意,这是一个有点简化的垃圾收集描述,但它仍然是一个有用/合理的心理模型,它是如何工作的)

所以简短的回答是 - “是的,你有一个循环引用。但这不是一个问题,因为一旦两个对象都不再可以转发,它们就会被收集”

答案 2 :(得分: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);
    ...
  }