我是不是通过显式处理 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