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(当它被删除时将被清理)。
假设我正在观察一个变量
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(当它被删除时将被清理)。