1

处理 Monotouch.Dialog 实例时:

  • 自定义UIBubbleMapElement元素由 GC 处理;
  • 对于每个已处置的元素,UIBubbleMapCellGC 也会处置一个自定义元素;
  • 但是对于所有已处置的单元格,他们的习惯UIBubbleMapView都没有被处置。

为了解决这个问题,我开始使用 Mono Profiler 应用程序。

Mono 分析器仅显示根引用。

问题是:查看未处理的UIBubbleMapView实例反向引用图像。我怎样才能发布最后一个引用并允许收集我的自定义视图?

最后,这是我的UIBubbleMapCelldispose 方法:

protected override void Dispose (bool disposing) {

    bubbleMapView = null;

    System.Diagnostics.Debug.WriteLine ("############# {0} 'Dispose' {1}.", this, disposing ? "invoked directly" : "called by the garbage collector finalizer");

    base.Dispose (disposing);
}

这就是我打印到控制台的内容:

############# <UIBubblesViewController: 0x152427c0> 'Dispose' called by the garbage collector finalizer.
############# <UIBubbleMapCell: 0x152b6a40; baseClass = UITableViewCell; frame = (0 195; 320 38); autoresize = W; layer = <CALayer: 0x152c65c0>> 'Dispose' called by the garbage collector finalizer.
############# <UIBubbleMapCell: 0x1524aba0; baseClass = UITableViewCell; frame = (0 35; 320 38); autoresize = W; layer = <CALayer: 0x152038f0>> 'Dispose' called by the garbage collector finalizer.
############# <UIBubbleMapCell: 0x17c91710; baseClass = UITableViewCell; frame = (0 233; 320 116); autoresize = W; layer = <CALayer: 0x152cbb80>> 'Dispose' called by the garbage collector finalizer.
############# <UIBubbleMapCell: 0x1520b2c0; baseClass = UITableViewCell; frame = (0 108; 320 52); autoresize = W; layer = <CALayer: 0x17c2fc30>> 'Dispose' called by the garbage collector finalizer.

编辑:感谢罗尔夫的回答。

首先,我在 UITableViewCell Dispose 方法中添加了以下代码:

bubbleMapView.Dispose ();
bubbleMapView = null;

尽管在控制台内收到下一条消息,但 Mono 分析器仍将对象显示为未收集。与以前相同的图像。

 ############# <UIBubbleMapView: 0x154af370; frame = (0 0; 1 1); layer = <CALayer: 0x154af0e0>> 'Dispose' invoked directly.

在仪器应用程序中运行时,我可以看到它的引用计数大于 1。

可见的内存泄漏。

图像中有一个UIBubbleTextView实例,但它的行为方式与实例完全相同UIBubbleMapView

UIBubbleMapView持有其他一些观点。这是未检查反向引用时的探查器信息。有一些技巧可以处理这些子视图吗?

没有反向引用

4

1 回答 1

3

<Other Root>通常是 GCHandle Xamarin.iOS 在内部使用以保持托管对象活动,直到相应的本机对象被释放。打破此链接的一种方法是在对象上调用 Dispose(您没有提到在 UIBubbleMapView 上调用 Dispose),在这种情况下,托管对象将由 GC 收集(当然,除非它被其他托管代码引用)。

很可能还有一些其他本机代码持有对此 UIBubbleMapView 实例的引用,但要准确找出您需要使用 Instruments 中的分配工具分析发生的情况(启用引用计数跟踪以准确跟踪保留对象的代码) .

更新

在您对托管对象调用 Dispose 之前,托管对象将保留本机对象 [1]。这意味着如果保留计数 > 1,则该对象还有额外的本机保留(这也意味着一旦您在对象上调用了 Dispose,剩余的引用都是本机的)。请注意,此时托管对象可能会被 GC 收集,因此您无法再使用 HeapShot 跟踪(本机)对象,您必须使用 Instruments。

提示:如果您在 Instruments 中启用右侧栏,您将获得每个保留/释放调用的堆栈跟踪。这对于追踪谁保留了一个对象非常有帮助。

[1] Xamarin.iOS 还将在保留计数达到 1 时释放托管对象的引用(并且 GC 已确定托管对象未被其他托管代码引用)。

于 2013-03-05T14:08:43.990 回答