我有一个具有UITabBarController的MonoTouch应用程序,每个选项卡都是一个UINavigationController。其中一些包装了一个UIViewController,它添加了一个UITableView和一个UIToolbar,其他包装了一个DialogViewController。我到目前为止还没有关注内存/视图管理(我一直主要在模拟器中运行),但由于我已经开始在真实设备上进行测试,所以我注意到由于低内存条件(例如,应用程序被终止,并且我从我的日志中发现DidReceiveMemoryWarning在此之前被调用)。其他时候,我注意到我假设的应用程序响应时间延长是由于GC循环造成的。使用MonoTouch和MonoTouch.Dialog进行内存/资源管理
到目前为止,我一直假设每一个我推入导航堆栈的DialogViewController都会清理它的视图以及在弹出时分配的其他东西。但是我开始意识到它可能并不那么容易,而且我需要开始对事物调用Dispose()。
是否有最佳做法来处理如何使用MonoTouch和MTD管理资源和内存?具体如下:
- 是否需要在DialogViewController弹出后调用Dispose?如果是这样,那么最好在哪里做? (ViewDidUnload?DidReceiveMemoryWarning?析构函数?)
- DVC是否自动处理传递给它的RootElement之类的对象,还是我需要担心这个问题?作为渲染表格单元(例如StyledStringElement)的一部分加载的UIImage如何?
- 有些地方我应该调用GC.Collect()以便更好地分配集合,以便在GC发生时不会在响应中产生一些影响?
- 世代垃圾回收器是否有助于解决交互问题,并且足够稳定以用于生产应用程序? (我相信在MonoDevelop 3.0.2/MT 4.3.3中它仍然是“实验性”)
- 我需要在DidReceiveMemoryWarning中做些什么来降低iOS拍摄我的应用程序的可能性?由于每个不可见的视图控制器似乎得到这个调用,我假设我应该清理该视图控制器的资源...我应该做同样的事情,我在ViewDidUnload做什么?
- 我似乎没有让我的ViewDidUnload调用(即使我得到DidReceiveMemoryWarning后)。事实上,我不记得在我的日志中看到过它。如果iOS总是在DidReceiveMemoryWarning之后调用我的ViewDidUnload,那么我只需要在ViewDidUnload中执行所有的清理操作...在ViewDidUnload和DidReceiveMemoryWarning之间拆分清理责任的最佳方式是什么?
我对这个问题的一般性质的道歉 - 这似乎是一个白皮书一个很好的话题,但我找不到任何...
更新:使问题更具体:在使用Instruments和Xamarin Heapshot分析器之后,当用户弹出导航堆栈时,很明显我泄漏了UIViewControllers。 Rolf为此提交了一份bug,它有两个孪生兄弟,所以这对我来说不仅仅是一个真正的问题。不幸的是,我还没有找到一个很好的解决办法,泄漏UIViewControllers - 我还没有找到一个好的地方调用他们的Dispose()。 ViewDidLoad分配资源的自然空间位于ViewDidUnload消息中,但它永远不会在模拟器上调用,因此我的内存占用量不断增长。在设备上,我看到了DidReceiveMemoryWarning,但我不愿意将它用作释放视图控制器及其资源的地方,因为我无法保证iOS实际上会卸载视图,因此不能保证我的ViewDidLoad会再次被调用(导致ViewDidAppear需要对其底层资源处置情况进行防御编码)。我很想得到一些关于如何摆脱这种混乱的建议...
这是一个很多有价值的信息,谢谢你把它放在一起。给未来的读者一个提示:从iOS 6开始,系统将不会调用ViewDidUnload。 –