开发人员有什么责任来破坏/清除之前在Control上创建和设置的模型?
给出以下初始化代码:
var oModel = new sap.ui.model.json.JSONModel();
var oData = new SomeData();
oModel.setData(oData);
this.setModel(oModel);
......退出时开发人员的责任是什么?环顾代码,我没有看到明确的答案。有些代码什么都不做,有些代码在退出时执行以下操作:
var oModel = this.getModel();
this.setModel(null);
oModel.destroy();
哪个是对的?开发人员有责任取消设置模型并将其销毁吗?或者UI5框架是否像聚合等那样处理?由于getModel可以返回父层次结构中定义的第一个模型,因此必须采取保护措施以确保在其他人可能正在使用的模型上不会意外地执行销毁?
根据文件here:
当用户关闭应用程序时,组件的销毁功能是 调用。所有型号和路由器都被销毁。路由器将采取 关心摧毁观点。
是否唯一一次在app退出时自动销毁模型(并且,作为MessageProcessors,从MessageManager取消注册)?在此期间,当涉及到解雇模型变更事件时,是否会导致许多模型在占用内存并不得不被筛选的可能性?
在控制台退出时销毁模型是否明智/安全,而不是等待应用程序退出,以便它不会徘徊并导致不断增长的内存占用?
答案 0 :(得分:1)
组件会破坏它创建的内容:组件元数据中定义的模型(请参阅OpenUI5 sources)。
UIComponent还会破坏路由器和创建的视图(sources)。相应的控制器将自己的onExit()
方法附加到视图beforeExit event。因此,您在控制器中创建的应该清理的所有内容都应该在那里进行清理。
现在有趣的问题是:让垃圾收集完成其工作来销毁不再存在的模型是否足够?并且破坏视图并删除其控制器真的删除了对本地模型的所有引用吗?或者某个地方有缓存吗?
简要介绍代码表明确实存在全局缓存:所有模型inherit from sap.ui.core.message.MessageProcessor。在其destroy方法中,从Cores MessageManager中取消注册...
我做了一个小实验:我创建了一个简单的测试页面,可以在视图的onInit()
中创建一个大型模型。在一次运行中,它会在视图的model.destroy()
中调用onExit()
。在第二次运行中,它不调用model.destroy()
。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<script src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js" id="sap-ui-bootstrap" data-sap-ui-theme="sap_bluecrystal" data-sap-ui-libs="sap.m"></script>
<script type="sapui5/xmlview" id="view1">
<mvc:View xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" controllerName="view1">
<Button text="close view" press=".closeView" />
</mvc:View>
</script>
</head>
<body id="body">
<script>
sap.ui.core.mvc.Controller.extend("view1",{
onInit:function(){
var data = [];
for(var i = 0; i<1000000; i++){
data.push({text: "Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla Bla"+i});
}
this.getView().setModel(new sap.ui.model.json.JSONModel(data));
},
onExit:function(){
this.getView().getModel().destroy();
},
closeView:function(){
this.getView().destroy();
}
});
var view = sap.ui.xmlview({viewContent: $("#view1").html()}).placeAt("body");
</script>
</body>
</html>
&#13;
以下屏幕截图显示了结果:
在onInit()
中,在堆上分配了大约140 MB。在第一次运行中,模型未明确销毁。在销毁视图并强制执行垃圾收集(Chromes Timeline的一项功能)后,只释放了几MB。可能是视图本身所需的内存。
在第二轮中model.destroy()
在视图的onExit()
中调用。在强制垃圾收集时完全释放分配的内存。
这加强了我的假设,你必须明确地销毁你正在创造自己的模型。