Skip to content

Range Controller Updates During Deallocation Can Cause Assertion Failure #212

@garrettmoon

Description

@garrettmoon

From @Adlai-Holler on March 31, 2017 22:19

  • ASCollectionNode in full range mode
  • Data source & delegate cleared (UICollectionView calls reloadData -> get empty data)
  • (No layout pass happens, old cells are still visible)
  • Removed from window
  • Interface state goes invisible
  • Range controller schedules to observe rendering notifications Update documentation of ASNetworkImageNodeDelegate #trivial #1163 <--- The problem
  • Later…
  • Rendering finishes
  • Range controller updates
  • Asks for visible elements. Gets the old index paths from last layout pass before controller dealloc.
  • Data controller's element map is empty, due to reloadData
  • Can't get the ASCollectionElement for the cell, fail assertion

Small Fix

Have the range controller only listen to rendering notifications when it's NOT in full mode. This seems solid, and I'll do it in a diff soon.

Medium Fix

Add a layoutIfNeeded call into [ASCollectionView visibleElementsForRangeController:] to ensure that the layout is up-to-date. I confirm that this fixes the issue in the limited case.

Large Fix

Stay in closer sync with UICollectionView by only actually committing reloadData when the layout pass happens. In some cases, we will need to manually trigger layout passes in order to get data preloading. @nguyenhuy toyed with this idea but had some issues – could you document them here?

Main Thread:

screen shot 2017-03-31 at 3 12 53 pm

Dealloc Queue Thread:
screen shot 2017-03-31 at 3 13 07 pm

@maicki @appleguy as well

Copied from original issue: facebookarchive/AsyncDisplayKit#3235

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions