我是不是通过显式处理 imageView.Image 来赢得内存?

Posted

技术标签:

【中文标题】我是不是通过显式处理 imageView.Image 来赢得内存?【英文标题】:Do I win memory by explicitly disposing imageView.Image?我是否通过显式处理 imageView.Image 来赢得内存? 【发布时间】:2013-04-24 21:39:52 【问题描述】:

我的应用中有这段代码:

var newImage = // ...

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

imageView.Image = newImage;

我有三个相关的问题:

是否立即释放之前imageView.Image占用的内存? 如果有,是否有更清洁的解决方案? 这和NSAutoreleasePool有关系吗?

【问题讨论】:

【参考方案1】:

是否立即释放之前imageView.Image占用的内存?

不是立即,但它应该比等待垃圾收集器快得多。

调用Dispose 将删除托管native UIImage 的引用。如果没有其他(本机)引用UIImage(RetainCount == 0),那么它将被释放(ObjC 引用计数)。

在您的代码中,imageView 仍然有对它的引用,直到它的 Image 属性设置为 newImage - 这就是我回答不是立即的原因。

如果是这样,有没有更清洁的解决方案?

不是真的。让 GC 完成它的工作看起来更干净 - 但图像可能非常大,值得尽快释放。

此外,添加一个局部变量以确保(如果不存在其他本机引用)图像将立即被释放(它会在下一行发生),这并不值得(并且无论如何也不会更干净)。

这和 NSAutoreleasePool 有关系吗?

什么?好吧,这两种情况都与内存有关。

创建图像将使用(缓存)当前的NSAutoreleasePool,并且最终会被耗尽。如果您处理很多东西(例如循环),那么通常值得拥有自己的短期池,以确保更快地排出。

一些 API(众所周知需要大量内存)用一个属性修饰,该属性会自动添加(btouch)NSAutoreleasePool - 但要找出哪个并不容易。

有疑问你最好使用 Apple Instruments 来测量...

【讨论】:

感谢您的快速回复,这或多或少是我所期望的。关于NSAutoreleasePool,我希望如果我将作业包装在一个专用池中,我就不必写这个if 条件。我想不是这样吧?恐怕我不明白 NSAutoreleasePool 在 MonoTouch 中应该如何使用,什么是 draining,以及它如何与 Mono 的 GC 一起使用。 NSAutoreleasePool 类似于 ObjC(Apple 文档适用),它与 GC(仅涵盖托管引用)直接相关,因为它是 native 参考将保存在池中。这也意味着它不能解决使用if 和调用Dispose。请参阅 Rolf 的答案 ***.com/a/10440506/220643 以获取 需要 的示例,但之前分配给 UIImageView.Image 的任何现有 UIImage 将不会被处置(在该示例中),直到 GC 处理它(所以最好在上面调用Dispose,如果不是null,就像你自己的例子一样)。

以上是关于我是不是通过显式处理 imageView.Image 来赢得内存?的主要内容,如果未能解决你的问题,请参考以下文章

当完成处理程序显式使用 @escaping 时,Swift 推断完成处理程序闭包是默认的 @nonescaping 而不是 @escaping

PHP是不是优化数组类型的函数参数,而不是通过引用显式传递,当它们没有被修改时?

我们是不是需要显式使用指针类型的 CTOR?

iOS-分享两个小问题

FtpWebRequest 使用显式 TLS/SSL

为啥我应该更喜欢“显式类型的初始化程序”习语而不是显式给出类型