何时以单声道触摸/ mvvmcross释放对象

Bja*_*rke 2 memory-management xamarin.ios mvvmcross

我们正在实现一个似乎有重大内存泄漏的应用程序.举个例子,我们有一个带有相应视图模型的视图,它在单声道探查器中被注册了38次,但它应该被垃圾收集.我们有很多自定义控件等,但这些应该放在哪里 - 从ios 6开始,viewdidunload不再被调用,所以我们应该在哪里进行清理?

问候

Stu*_*art 5

这是一个很大的问题......并且不能轻易地回答一般情况.

一般来说,如果你编写漂亮的简单ViewModel和简单的简单视图,那么你就不会有任何内存泄漏.

但是,如果您有引用ViewModel的视图,而ViewModel又以某种方式引用了视图,则很可能会导致内存泄漏 - 特别是如果您的视图模型订阅了服务上的事件.


一个特别令人讨厌的情况是ObjC和C#都引用了对象.在http://forums.xamarin.com/discussion/97/correct-way-to-pop-a-dialogviewcontroller-mine-are-staying-in-memory上对此进行了一些讨论,这也引用了我们曾经遇到过的问题. SQL位示例 - https://github.com/slodge/MvvmCross/issues/19

这可能不是你当前泄漏的情况,但值得阅读Rolf的答案 - http://forums.xamarin.com/discussion/comment/535/#Comment_535 - 几次 - 这不是入门级解释,但它最终有道理!


所以,为了解决你当前的问题......

  1. 弄清楚什么是泄漏

  2. 弄清楚为什么 - 这是什么坚持参考.

  3. 修理它.

关键是要投入相当多的精力去研究1和2,然后再深入研究错误的修复3.在没有真正知道它是什么的情况下尝试"修复它"是没有意义的.

好消息是Mono分析器 - 内置工具来识别什么引用了什么 - 对于帮助完成这项工作非常有用.

根据您的描述,我知道您已经找到了这个工具 - 但对于其他人来说,请参阅 - http://docs.xamarin.com/ios/Guides/Deployment%252c_Testing%252c_and_Metrics/Monotouch_Profiler


有一次,你已经确定了泄漏的原因和原因,然后第3步需要一些思考,但希望很容易回答.

有时解决方案是:

  • 只需修复一行不好的代码......哪一行是硬位.
  • 使用"后退"检测,确定何时断开绑定或事件.
  • 使用'willappear','willdisappear'添加生命周期事件以更改订阅/取消订阅事件的方式
  • 使用除C#事件之外的替代方法 - 例如使用诸如TinyMessenger(或MvvmCross插件信使)之WeakReference类的Messenger - 这些方法的优点是它们通常使用类来避免泄漏.
  • 在"适当的时间"处理'某事' - 再次解决'某事'而'适当的时间'是这个问题的难点

无论发生什么,不要惊慌,并从工程角度解决这个问题.这些泄漏也发生在非MvvmCross和非MonoTouch代码中 - 并且使用具有良好干净的IoC架构的MvvmCross应该使它们更容易查找和删除.


如果问题确实发生在某个地方的MvvmCross绑定中,那么请将其记录为一个错误 - 我非常认真地对待这些问题!

在关于MvvmCross回购的长篇讨论中,关于我们是否应该将WeakReferences用于所有绑定代码仍有一个漏洞 - 请参阅https://github.com/slodge/MvvmCross/issues/17 - 我考虑过这样做这 - 它可以帮助人们避免一些错误......但不是全部.那个问题仍然存在.


更新:我没有回答

我们有很多自定义控件等,但应该在哪里处理

框架应该为您处理这些.

如果没有那么那可能是因为其他东西正在泄漏并持有你的View,然后继续你的控件.您需要修复该底层问题,而不是过早地在控件上调用Dispose().内存泄漏调试并不容易,但有点好玩(有时候)