我通过显式释放imageView.Image来获得内存吗?

3

我在我的应用程序中有这段代码:

var newImage = // ...

if (imageView.Image != null && imageView.Image != newImage)
    imageView.Image.Dispose ();

imageView.Image = newImage;

我有三个相关的问题:

  • 它是否立即释放先前的 imageView.Image 占用的内存?
  • 如果是,有更干净的解决方案吗?
  • 这是否与 NSAutoreleasePool 有关?
1个回答

6
它会立即释放先前imageView.Image所占用的内存吗? 不是立即,但比等待垃圾收集器要快得多。
调用Dispose将删除对本机UIImage托管引用。如果没有其他东西(在本地)对UIImage进行引用(RetainCount == 0),则它将被释放(ObjC引用计数)。
在您的代码中,直到将Image属性设置为newImageimageView仍然引用它,这就是为什么我回答不是立即的原因。
它是否有更干净的解决方案?
实际上没有。让GC去做它的工作看起来更简洁-但图像可能非常大,值得尽早释放。
另外,添加一个局部变量以确保(如果没有其他本地引用存在),图像将立即释放并不值得(也不会更加简洁)-它将在下一行发生。
这与NSAutoreleasePool有关吗?
任何?在这两种情况下都涉及内存相关。
创建图像将使用(缓存)当前的NSAutoreleasePool,并且最终将被排空。如果您处理大量内容(例如循环),则通常值得拥有自己的短暂池,以确保更快的排放。
一些API(众所周知需要大量内存)带有属性,将自动添加(btouch)NSAutoreleasePool,但很难找出哪个。
如果不确定最好使用Apple Instruments进行测量...

感谢您的快速回复,这基本上是我预期的。关于NSAutoreleasePool,我希望如果我将赋值包装在专用池中,就不必编写此if条件。我猜这不是这种情况吗?恐怕我不明白在MonoTouch中应该如何使用NSAutoreleasePool,什么是draining以及它如何与Mono的GC配合。 - Dan Abramov
2
NSAutoreleasePool 就像 ObjC(适用于 Apple 文档),它与 GC(仅涵盖托管引用)没有直接关系,因为它是一个本地引用,将被保存在池中。这也意味着它不能通过使用 if 和调用 Dispose解决问题。请参见 Rolf 的答案 https://dev59.com/IGPVa4cB1Zd3GeqP4ENF#10440506,其中举了一个需要使用 NSAutoreleasePool 的示例,但是任何先前存在的分配给 UIImageView.ImageUIImage(在该示例中)不会被释放,直到 GC 处理它(因此最好像您自己的示例一样,在其上调用 Dispose,如果不为空)。 - poupou

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接