Omr*_*itt 19 memory-management xamarin.ios ios monotouch.dialog
我有一个具有UITabBarController的MonoTouch应用程序,每个选项卡都是UINavigationController.其中一些包装UIViewController,它添加一个UITableView和一个UIToolbar,其他包装一个DialogViewController.
到目前为止,我没有太多关注内存/视图管理(我一直在模拟器中运行),但是当我开始在真实设备上进行测试时,我注意到由于内存条件不足导致的一些故障(例如,应用程序被终止,我从我的日志中发现在此之前调用了DidReceiveMemoryWarning).其他时候我注意到应用程序响应性的长时间暂停,我假设是由于GC循环.
到目前为止,我一直在假设我推送到导航堆栈的每个DialogViewController都会清理它的视图以及当我弹出它时分配的其他东西.但我开始意识到它可能并不那么容易,而且我需要开始调用Dispose().
有没有关于如何使用MonoTouch和MT.D处理资源和内存的最佳实践?特别:
我为这个问题的一般性质道歉 - 这似乎是白皮书的一个好主题,但我找不到任何......
更新:使问题更具体:在使用Instruments和Xamarin Heapshot Profiler之后,我很清楚当用户弹出导航堆栈时我正在泄漏UIViewControllers.Rolf 为此提出了一个错误,它有两个重复,所以这不仅仅是我的真正问题.不幸的是,我没有找到泄漏的UIViewControllers的好方法 - 我还没有找到一个调用Dispose()的好地方.释放ViewDidLoad分配的资源的自然位置在ViewDidUnload消息中,但它永远不会在模拟器上调用,因此我的内存占用量不断增长.在设备上,我确实看到了DidReceiveMemoryWarning,但我不愿意使用它作为释放我的viewcontroller及其资源的地方,因为我无法保证iOS实际上会卸载我的视图,因此无法保证我的ViewDidLoad会再次被调用要么(导致ViewDidAppear需要针对其底层资源处置的情况进行防御性编码).我很想得到一些关于如何摆脱这个烂摊子的建议......
Omr*_*itt 30
我在MT.D源代码和分析器中花了几天时间.虽然我仍在寻找有关实现DidReceiveMemoryWarning和ViewDidUnload的最佳设计模式的一般指导,但我确实有一些一般的观察要分享,这可能对某些人有用:
一般来说,我遵循以下模板来分配视图控制器中的对象:
当用户导航导航堆栈时,存在导致ViewControllers泄漏的一般问题(我在问题中的"更新"中引用了bugzilla链接).这也影响了MT.D. 有一个相当简单的解决方法 - 在父视图控制器的ViewDidAppear中添加以下代码行:
// HACK: touch the ViewControllers array to refresh it (in case the user popped the nav stack)
// this is to work around a bug in monotouch (https://bugzilla.xamarin.com/show_bug.cgi?id=1889)
// where the UINavigationController leaks UIViewControllers when the user pops the nav stack
int count = this.NavigationController.ViewControllers.Length;
Run Code Online (Sandbox Code Playgroud)Rolf很好地解释了为什么会发生这个bug以及为什么解决方法在bugzilla链接中有效,所以我不再重复了.
我希望有人觉得这很有用.我也希望比我聪明的人有一些关于如何处理DidReceiveMemoryWarning以及如何在该方法和ViewDidUnload之间进行分工的指导.
更新:还有几点说明:
我的应用程序有一个TabBar,其中每个选项卡都包含一个UINavigationController,其中大多数都推送一个DialogViewController.我正在处理的一个问题是在ViewDidUnload放弃对它的引用之后泄漏了DialogViewController.我尝试在ViewDidUnload中处理DVC,但iOS仍然想要重新调用它,并且我在GC'ed对象上调用选择器时遇到异常.我发现了原因 - 导航控制器在其ViewControllers数组中保持着DVC.解决方案是通过在ViewDidUnload中创建一个零长度数组来释放数组:
this.ViewControllers = new UIViewController[0];
Run Code Online (Sandbox Code Playgroud)旧阵列现在将被GC,DVC也将如此,因为没有任何东西指向它了.并且iOS不会重新调用该对象.注意 - 无需在DVC上调用Dispose.
| 归档时间: |
|
| 查看次数: |
3174 次 |
| 最近记录: |