我差不多完成了我的第一个monotouch应用程序,几乎就是这样,但是对于内存泄漏的一些大问题。即使我在每个视图控制器上覆盖viewDidUnload,以便为我创建的每个UI元素首先从超级视图中删除它,然后调用Dispose然后将其设置为null,问题仍然存在。使用Instruments没有帮助,它不会检测内存泄漏,内存分配也不会指向我可以跟踪的任何内容。
我的应用主要使用MPMoviePlayer播放视频流,还会显示通过http加载的图像的图库。这两种操作都会造成问题。
非常感谢任何想法,谢谢。
答案 0 :(得分:6)
师父当然是对的。格拉西亚斯米格尔。我想要对我所做的事情做一个更全面的解释,希望它可以帮助未来的Xamarin学院。
1)MPMoviePlayer存储一种粘性的视频缓冲区。我所做的是在AppDelegate上运行一个独特的实例,并在显示视频的视图中重复使用它。因此,不是使用url初始化MPMoviePlayerController,而是使用不带参数的构造函数,然后设置ContentUrl属性并调用Play()。
2)不要依赖于调用ViewDidUnload来清理对象,因为它不会被一致地调用。例如,我使用了很多模态视图控制器,这种方法永远不会被调用。内存不断积累,直到应用程序崩溃。最好叫你直接清理代码。
3)图像是我拥有的最大记忆拥抱。甚至UIImageViews中仅用作背景的图像也永远不会被处理掉。在清理内存之前,我必须在每个图像上专门调用以下代码:
myImageView.RemoveFromSuperview();
myImageView.Image.Dispose();
myImageView.Image = null;
myImageView.Dispose();
myImageView = null;
4)小心UIWebView,它可以拥抱大量内存,特别是如果你正在加载的页面上运行某种类型的AJAX交互。调用以下代码有点帮助,但没有解决所有问题。一些内存泄漏仍然是我无法摆脱:
NSString keyStr = new NSString("WebKitCacheModelPreferenceKey");
NSUserDefaults.StandardUserDefaults.SetValueForKey(NSObject.FromObject(val), keyStr);
5)如果可以,请避免使用Interface Builder。有几次我无法释放在xib文件上创建的UI元素。手动定位所有内容可能会很麻烦,但如果您使用内存密集型应用程序,则可能需要在代码中创建所有视图控制器。
6)使用匿名方法作为事件处理程序很好,我的帮助代码可读性,但在某些情况下无法手动分离事件处理程序成为一个问题。对不需要的对象的引用仍保留在内存中。
7)在我的UITableViewSource中,我能够通过创建UIImages来更有效地进行内存处理,我用它来独立地设置单元格的样式,然后在我的GetViewForHeader和GetCell方法上重用它们。
最后一件事;尽管仪器与monotouch使用“内存监视器”做事的方式并不完全兼容,但这是一个很有价值的工具,如果你遇到问题它确实可以提供帮助。
这些策略解决了我的大部分问题。事后看来有些可能非常明显,但我认为传递它们并不会有什么坏处。
iPhone上的快乐编码和万岁c#
答案 1 :(得分:0)
UI元素不太可能是负责任的元素,那些几乎不使用任何内存。并且调用Dispose()/ nulling会有所帮助,但只有一点点。
更可能的问题来源是MPMoviePlayer,图像下载和图像渲染等对象。您可能会保留对那些阻止GC去除它们的对象的引用。