通过显式处理imageView.Image来赢取内存吗?

Dan*_*mov 2 garbage-collection dispose memory-management xamarin.ios nsautoreleasepool

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

var newImage = // ...

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

imageView.Image = newImage;
Run Code Online (Sandbox Code Playgroud)

我有三个相关的问题:

  • 它会立即释放前一个占用的内存imageView.Image吗?
  • 如果是的话,是否有更清洁的解决方案?
  • 这有什么关系NSAutoreleasePool吗?

pou*_*pou 6

它会立即释放前一个imageView.Image所占用的内存吗?

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

调用Dispose将删除托管引用到本 UIImage.如果没有别的(本机地)引用UIImage(RetainCount == 0)那么它将被释放(ObjC引用计数).

在你的代码imageView仍然有一个引用它,直到它的Image属性设置为newImage- 这就是我没有立即回答的原因.

如果是的话,是否有更清洁的解决方案?

并不是的.让GC做它的工作看起来更干净 - 但是图像可能非常大并且值得尽快释放.

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

这与NSAutoreleasePool有什么关系吗?

还有什么?这两种情况都与记忆有关.

创建图像将使用(缓存)当前NSAutoreleasePool和最终将被耗尽.如果你处理很多东西(例如一个循环),那么通常你需要拥有自己的,短命的池来确保更快的消耗.

一些API(众所周知需要大量内存)装饰有一个会自动添加(btouch)的属性NSAutoreleasePool- 但要找出哪个属性并不容易.

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

  • `NSAutoreleasePool`就像ObjC(Apple文档适用),并且它**不直接与GC相关(仅涵盖托管引用),因为它是**本地**引用将保留在池中.这也意味着它不会*使用`if`并调用`Dispose`来解决*.请参阅Rolf的答案http://stackoverflow.com/a/10440506/220643,其中**需要*,但之前存在的,分配给`UIImageView.Image`的`UIImage`将不会被处理掉(在那里)例子)直到GC处理它(所以最好在它上面调用`Dispose`,如果不是null,就像你自己的例子一样). (2认同)