我正在尝试使用Android数据绑定的MVVM。我的代码如下:
public class ... extends Activity {
...
private CommentViewModel viewModel;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, provideLayout());
viewModel = new CommentViewModel(this);
binding.setViewModel(viewModel);
}
@Override
protected void onDestroy() {
viewModel = null; //setting view model to null to avoid leaks
super.onDestroy();
}
}
我想要做的是在ViewModel
中将onDestroy()
设置为null以避免任何可能的泄漏。
由于我的ViewModel
本身会将一些callbacks
注册到其他组件并使用可能泄漏的context
,如果其中一个回调未被删除且上下文传递到某处,我决定设置它空。
但是我的同事开了一个有趣的讨论,他说这是一个过时的做法,因为'Effective Java'表明这就是你在C ++中的表现。他说,一个好方法是从ViewModel中删除所有回调,而不是将其设置为null。类似的东西:
public class ... extends Activity {
...
private CommentViewModel viewModel;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
...//same as above
}
@Override
protected void onDestroy() {
viewModel.removeCallbacks(); //removing all callbacks from view model to avoid leaks
super.onDestroy();
}
}
现在这两种方法都运行良好,但在第一种方法中,我非常确信泄漏不会发生。但结果,它看起来有些难看。第二种方法很好但它迫使我考虑ViewModel
中可能发生的所有可能的泄漏。
这可能是一个普遍的问题:您认为哪种方法更好,为什么?
答案 0 :(得分:0)
没有比像
这样的事情更令人恼火的了System.gc()
在大型应用的生产代码中。中间件工程师的工作就是调整JVM以及如何管理内存 - 我真的像这些人一样说话。在你的情况下,事情是相同的,开发Android的人最了解如何管理GC。如果不能使任何更清晰/更容易理解的代码,你就不应该编写更多的代码。
经验丰富的程序员应该知道与框架相关的所有肮脏技巧(例如:stackoverflow.com/questions/13534030/can-a-scheduled-future-cause-a-memory-leak)以及如何不取消,而不是取消引用,关闭等可能会导致内存泄漏。
在你的情况下,更重要的是,你可以想象会有相当复杂的回调(让我们说它们是循环的,并且有数千个),并且使你的引用为空赢了# 39;为GC更容易,但删除回调将会。