Roku:在观察未使用的变量后取消观察它们是标准做法吗?

Roku: Is it standard practice to unobserve unused variables after observing them?

假设我正在观察一个变量

m.someObject.observeField("content", "onContentChanged")

一段时间后我不再需要m.someObject。 我需要清理并调用

m.someObject.unobserveField("content")

或者我可以离开吗?

是的,你应该。 Roku 没有世界上最强大的垃圾回收系统,但我们注意到通过谨慎处理这一点可显着提高性能。

是的,尝试将此作为一个好习惯,就像处理 open() 之后的文件最终应该调用 close() 一样(即使,一般来说,超出范围会负责关闭连接,明确处理它是一个好习惯)。

现在,请注意 node.unobserveField("X") 是一个 "nuclear" 选项,因为它会丢弃 任何和所有 观察者 node.X node.observeField("X", ...),无论它们来自哪个组件或线程。因此,如果每个字段有多个观察者,您可能会后悔并最终完全避免使用 unobserveField()。请注意,当 node 被销毁时,这些观察者将得到处理(即不是内存泄漏)。

现在,还有一个更新的 API 在许多情况下更好 - 这些方法的“...Scoped()”版本。在那个版本中,node.unobserveFieldScoped("X") 更具选择性——它只删除 node.X 上由 当前组件 放置的观察者;其他组件设置的观察者保持活跃。

对我来说,通过思考 其中 是观察者 link 的存储,更容易区分这两种方法。在非范围版本中,所有 links 都与观察对象一起存储 - 因此析构函数负责清理 links。在范围版本中,links 与每个观察组件一起存储 - 因此 Unobserve 仅在本地对这些组件起作用。所以我相信有一个警告 - 如果 observED 对象被销毁,它会(暂时)在 observING 对象中留下一些悬挂的 scoped links。相反,如果使用了非作用域的 ObserveField(),则 observING 对象的销毁将在 observED 对象中留下未清理的 link(当它被删除时将被清理)。