تكرار السؤال: …
الإجابة المختصرة
يمتلك الـ Fragment دورتي حياة: واحدة للـ Fragment نفسه وأخرى لواجهته (View)، ويجب استخدام viewLifecycleOwner لمراقبة البيانات لتفادي تسريب الذاكرة.
الشرح
عند إضافة الـ Fragment إلى الـ Backstack واستبداله، يتم تدمير واجهته فقط (onDestroyView) بينما يبقى كائن الـ Fragment حيًا في الذاكرة. إذا تم تسجيل مراقب (Observer) باستخدام this، فسيستمر في استقبال البيانات والاحتفاظ بواجهات قديمة مهملة، لذلك يجب دائمًا استخدام viewLifecycleOwner الذي ينتهي بمجرد تدمير الـ View.
مثال بالكود
class UserFragment : Fragment(R.layout.fragment_user) {
private val viewModel: UserViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Correct: tie collection to the VIEW's lifecycle, not the Fragment's
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.userFlow.collect { user -> bindUser(user) }
}
}
}
}أخطاء شائعة
- تمرير this كـ LifecycleOwner لمراقبة LiveData أو Flow داخل الـ Fragment بدلاً من viewLifecycleOwner.
- الاحتفاظ بمرجع قوي لـ ViewBinding دون تفريغه في onDestroyView، مما يسبب Memory Leak.