Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent stale adapter:collectionView corruptions #517

Closed
wants to merge 3 commits into from

Conversation

rnystrom
Copy link
Contributor

@rnystrom rnystrom commented Feb 27, 2017

Changes in this pull request

This becomes an issue pretty easily in embedded IGListAdapter environments (lists in lists). IGListKit creates a single IGListSectionController instance per object, but cells are reused within IGListCollectionView. If you assign adapter.collectionView = cell.collectionView (like we recommend in our example), then you can have many adapters with a weak ref to the same collection view.

Obviously when updates happen across all embedded lists, adapters could potentially update the same collection view and apply a corrupted batch update.

I proposed using <objc/runtime.h> and using associated objects, but since OBJC_ASSOCIATION_ASSIGN is not zerod-on-release reference (its just unsafe_unretained) I'd have to make a weak wrapped object, which is overkill.

Instead I think a global weak:weak map is fine. We don't have to worry about locking b/c of the main-thread affinity of the framework. Please push back on me if you have a better idea.

Issue fixed: #503

Checklist

  • All tests pass. Demo project builds and runs.
  • I added tests, an experiment, or detailed why my change isn't tested.
  • I added an entry to the CHANGELOG.md for any breaking changes, enhancements, or bug fixes.

@rnystrom rnystrom added this to the 3.0.0 milestone Feb 27, 2017
@facebook-github-bot
Copy link
Contributor

@rnystrom updated the pull request - view changes

@rnystrom
Copy link
Contributor Author

Importing b/c our CI is faster than Travis.

@facebook-github-bot
Copy link
Contributor

@rnystrom has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@jessesquires
Copy link
Contributor

our CI is faster than Travis.

lol

@@ -62,13 +62,23 @@ - (IGListCollectionView *)collectionView {
return (IGListCollectionView *)_collectionView;
}

static void *kIGListCollectionViewAdapterKey = &kIGListCollectionViewAdapterKey;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is this used? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not 😅

- (void)setCollectionView:(IGListCollectionView *)collectionView {
IGAssertMainThread();
IGParameterAssert([collectionView isKindOfClass:[IGListCollectionView class]]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unrelated to this PR? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have to remove so we can set to nil


// if collection view has been used by a different list adapter, treat it as if we were using a new collection view
// this happens when embedding a IGListCollectionView inside a UICollectionViewCell that is reused
if (_collectionView != collectionView || _collectionView.dataSource != self) {
// if the collection view was being used with another IGListAdapter (e.g. cell reuse)
// destroy the previous association so the old adapter doesn't update the wrong collection view
static NSMapTable<IGListCollectionView *, IGListAdapter *> *globalCollectionViewAdapterMap = nil;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we're main-thread-only, but should we still consider using dispatch_once ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally fine if main-thread affined, dispatch_once will add unused overhead

@jessesquires
Copy link
Contributor

💯

Copy link
Contributor

@jessesquires jessesquires left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🌮

@facebook-github-bot
Copy link
Contributor

@rnystrom updated the pull request - view changes - changes since last import

@facebook-github-bot
Copy link
Contributor

@rnystrom has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@jessesquires jessesquires deleted the collectionview-reuse branch February 28, 2017 15:39
@heumn
Copy link
Contributor

heumn commented Feb 28, 2017

thisisgiphy-reaction-audience-l4HodBpDmoMA5p9bG

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Out of bounds collectionview update (crash)
4 participants