void ViewReusePoolMap::reset()

in RenderCore/View/ComponentViewManager.mm [185:230]


void ViewReusePoolMap::reset(UIView *container, CK::Component::MountAnalyticsContext *mountAnalyticsContext) noexcept
{
  for (auto &it : dictionary) {
    it.second.reset(mountAnalyticsContext);
  }

  // Now we need to ensure that the ordering of container.subviews matches vendedViews.
  NSMutableArray *subviews = [[container subviews] mutableCopy];
  std::vector<UIView *>::const_iterator nextVendedViewIt = vendedViews.cbegin();

  // Can't use NSFastEnumeration since we mutate subviews during enumeration.
  for (NSUInteger i = 0; i < [subviews count]; i++) {
    UIView *subview = subviews[i];

    // We use linear search here. We could create a std::unordered_set of vended views, but given the typical size of
    // the list of vended views, I guessed a linear search would probably be faster considering constant factors.
    const auto &vendedViewIt = std::find(nextVendedViewIt, vendedViews.cend(), subview);

    if (vendedViewIt == vendedViews.cend()) {
      // Ignore subviews not created by components infra, or that were not vended during this pass (they are hidden).
      continue;
    }

    if (vendedViewIt != nextVendedViewIt) {
      NSUInteger swapIndex = [subviews indexOfObjectIdenticalTo:*nextVendedViewIt];
      // This check can cause some z-ordering issue if views vended by the framework are manipulated outside of the framework,
      if (swapIndex != NSNotFound) {
        // This naive algorithm does not do the minimal number of swaps. But it's simple, and swaps should be relatively
        // rare in any case, so let's go with it.
        [subviews exchangeObjectAtIndex:i withObjectAtIndex:swapIndex];
        [container exchangeSubviewAtIndex:i withSubviewAtIndex:swapIndex];
      }
      RCCAssertWithCategory(swapIndex != NSNotFound,
                            [CKMountedObjectForView(*nextVendedViewIt) class],
                            @"Expected to find subview %@ (mounted object: %@) in %@ (mounted object: %@)",
                            [*nextVendedViewIt class],
                            [CKMountedObjectForView(*nextVendedViewIt) class],
                            [container class],
                            [CKMountedObjectForView(container) class]);
    }

    ++nextVendedViewIt;
  }

  vendedViews.clear();
}