【发布时间】:2018-10-07 06:49:20
【问题描述】:
假设我在观察一个变量
m.someObject.observeField("content", "onContentChanged")
一段时间后我不再需要m.someObject。
我需要清理并打电话吗
m.someObject.unobserveField("content")
或者我可以离开它吗?
【问题讨论】:
标签: roku brightscript
假设我在观察一个变量
m.someObject.observeField("content", "onContentChanged")
一段时间后我不再需要m.someObject。
我需要清理并打电话吗
m.someObject.unobserveField("content")
或者我可以离开它吗?
【问题讨论】:
标签: roku brightscript
是的,尝试将此作为一种好的做法,就像在处理 open() 之后的文件时最终应该调用 close() 一样(即使一般来说,超出范围会关闭连接,这是一个好习惯明确地照顾它)。
现在,请注意 node.unobserveField("X") 是一个“核”选项,因为它会在 node.X 上丢弃 任何和所有 观察者,这些观察者与 node.observeField("X", ...) 一起放置,无论它们来自哪个组件或线程来了。因此,如果每个字段有多个观察者,您最终可能会后悔并最终完全避免使用 unobserveField()。请注意,当node 被销毁时,这些观察者将得到处理(即不是内存泄漏)。
现在,还有一个在许多情况下更好的更新 API - 这些方法的“...Scoped()”版本。在那个版本中,node.unobserveFieldScoped("X") 更具选择性 - 它只删除 node.X 上由 当前组件 放置的观察者;其他组件设置的观察者保持活动状态。
对我来说,通过考虑 where 是存储的观察者链接,更容易区分这两种方法。在非作用域版本中,所有链接都与观察对象一起存储 - 因此析构函数负责清理链接。在作用域版本中,链接与每个观察组件一起存储 - 因此 Unobserve 仅在本地对这些组件起作用。所以我相信有一个警告 - 如果观察到的对象被破坏,它将(暂时)在观察对象中留下一些悬挂的作用域链接。相反,如果使用了非作用域的 ObserveField(),则 observING 对象的销毁将在 observED 对象中留下未清理的链接(当它被丢弃时将被清理)。
【讨论】:
是的,你应该这样做。 Roku 没有世界上最好的垃圾收集器,我们注意到通过谨慎处理可以显着提高性能。
【讨论】: