为什么片段中“by lazy”委托的这种奇怪行为
Why this strange behaviour of the `by lazy` delegate in fragments
几天前,我发布了 关于在屏幕中多次包含相同布局时使用合成属性的问题。
答案很棒,但在我多试了几天之后,我发现了一个奇怪的行为:
当从片段(包含对惰性委托获得的视图的引用的片段)前进然后返回时(我使用 transaction.commit()
和 manager.popBackStack()
,来做到这一点),标签将为空。我已经用调试器检查过那里是否有任何东西是空的,但什么都没有。
唯一可行的解决方案是将 by lazy
替换为 lateinit var
并将它们分配到 onViewCreated
.
你知道为什么吗?我使用的解决方案是否仍然 "good" 作为 kotlin 习语?
为了完整起见,我包括了两段代码:
部分工作:
private val foundTitle by lazy { detailContainer1.title }
private val foundDescription by lazy { detailContainer1.description }
private val wantedTitle by lazy { detailContainer2.title }
private val wantedDescription by lazy { detailContainer2.description }
一直在工作一个:
private lateinit var foundTitle: TextView
private lateinit var foundDescription: TextView
private lateinit var wantedTitle: TextView
private lateinit var wantedDescription: TextView
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
foundTitle = detailContainer1.title
foundDescription = detailContainer1.description
wantedTitle = detailContainer2.title
wantedDescription = detailContainer2.description
}
提前致谢
Fragment 的视图在被移除时会被销毁 - 但 lazy
字段不会清除它们的引用,因此它们实际上是在泄漏以前的视图。
如果可能,您应该在您的项目中始终拥有唯一的视图 ID,即使它们不在同一布局中 - 重复可能会导致多个问题(就像您的一样)。
如果你能直接使用kotlin extensions,它会在片段视图自动销毁时生成查找、缓存和清除视图缓存的代码。
尝试 "get" 来自片段缓存的视图,而不是将它们分配给字段:
private val foundTitle
get() = detailContainer1.title
private val foundDescription
get() = detailContainer1.description
private val wantedTitle
get() = detailContainer2.title
private val wantedDescription
get() = detailContainer2.description
几天前,我发布了
答案很棒,但在我多试了几天之后,我发现了一个奇怪的行为:
当从片段(包含对惰性委托获得的视图的引用的片段)前进然后返回时(我使用 transaction.commit()
和 manager.popBackStack()
,来做到这一点),标签将为空。我已经用调试器检查过那里是否有任何东西是空的,但什么都没有。
唯一可行的解决方案是将 by lazy
替换为 lateinit var
并将它们分配到 onViewCreated
.
你知道为什么吗?我使用的解决方案是否仍然 "good" 作为 kotlin 习语?
为了完整起见,我包括了两段代码:
部分工作:
private val foundTitle by lazy { detailContainer1.title }
private val foundDescription by lazy { detailContainer1.description }
private val wantedTitle by lazy { detailContainer2.title }
private val wantedDescription by lazy { detailContainer2.description }
一直在工作一个:
private lateinit var foundTitle: TextView
private lateinit var foundDescription: TextView
private lateinit var wantedTitle: TextView
private lateinit var wantedDescription: TextView
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
foundTitle = detailContainer1.title
foundDescription = detailContainer1.description
wantedTitle = detailContainer2.title
wantedDescription = detailContainer2.description
}
提前致谢
Fragment 的视图在被移除时会被销毁 - 但 lazy
字段不会清除它们的引用,因此它们实际上是在泄漏以前的视图。
如果可能,您应该在您的项目中始终拥有唯一的视图 ID,即使它们不在同一布局中 - 重复可能会导致多个问题(就像您的一样)。
如果你能直接使用kotlin extensions,它会在片段视图自动销毁时生成查找、缓存和清除视图缓存的代码。
尝试 "get" 来自片段缓存的视图,而不是将它们分配给字段:
private val foundTitle
get() = detailContainer1.title
private val foundDescription
get() = detailContainer1.description
private val wantedTitle
get() = detailContainer2.title
private val wantedDescription
get() = detailContainer2.description