From 5fa588ee70fd167ed37392d52ee90f03a6d2c4d4 Mon Sep 17 00:00:00 2001 From: Adlai Holler Date: Tue, 3 Jan 2017 16:57:23 -0800 Subject: [PATCH] Make -[IGListAdapter updater] Public, Read-Only Summary: Hey IGListKit folks! Would you be willing to expose this, so that other objects that are given a list adapter can inspect its updater configuration? - [x] All tests pass. Demo project builds and runs. - [x] I added tests, an experiment, or detailed why my change isn't tested. - [x] I added an entry to the `CHANGELOG.md` for any breaking changes, enhancements, or bug fixes. - [x] I have reviewed the [contributing guide](https://github.com/Instagram/IGListKit/blob/master/.github/CONTRIBUTING.md) Closes https://github.com/Instagram/IGListKit/pull/379 Reviewed By: jessesquires Differential Revision: D4379016 Pulled By: rnystrom fbshipit-source-id: 4056457181fea31f71b1e928b60aec46160cc585 --- CHANGELOG.md | 2 ++ Source/IGListAdapter.h | 9 +++++++-- Source/IGListAdapter.m | 24 ++++++++++++------------ Source/Internal/IGListAdapterInternal.h | 2 +- Tests/IGListAdapterTests.m | 8 ++++---- 5 files changed, 26 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7177f7aa..afc58d8ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ This release closes the [2.1.0 milestone](https://github.com/Instagram/IGListKit - Added `allowsBackgroundReloading` flag (default `YES`) to `IGListAdapterUpdater` so users can configure this behavior as needed. [Adlai-Holler](https://github.com/Adlai-Holler) [(#375)](https://github.com/Instagram/IGListKit/pull/375) +- `-[IGListAdapter updater]` is now public (read-only). [Adlai-Holler](https://github.com/Adlai-Holler) [(#379)](https://github.com/Instagram/IGListKit/pull/379) + ### Fixes - Avoid `UICollectionView` crashes when queueing a reload and insert/delete on the same item as well as reloading an item in a section that is animating. [Ryan Nystrom](https://github.com/rnystrom) [(#325)](https://github.com/Instagram/IGListKit/pull/325) diff --git a/Source/IGListAdapter.h b/Source/IGListAdapter.h index cbbac7665..328d3ff23 100644 --- a/Source/IGListAdapter.h +++ b/Source/IGListAdapter.h @@ -73,6 +73,11 @@ IGLK_SUBCLASSING_RESTRICTED */ @property (nonatomic, nullable, weak) id scrollViewDelegate; +/** + The updater that this list adapter was created with. + */ +@property (nonatomic, strong, readonly) id updater; + /** A bitmask of experiments to conduct on the adapter. */ @@ -81,7 +86,7 @@ IGLK_SUBCLASSING_RESTRICTED /** Initializes a new `IGListAdapter` object. - @param updatingDelegate An object that manages updates to the collection view. + @param updater An object that manages updates to the collection view. @param viewController The view controller that will house the adapter. @param workingRangeSize The number of objects before and after the viewport to consider within the working range. @@ -94,7 +99,7 @@ IGLK_SUBCLASSING_RESTRICTED To opt out of using the working range, you can provide a value of `0`. */ -- (instancetype)initWithUpdater:(id )updatingDelegate +- (instancetype)initWithUpdater:(id )updater viewController:(nullable UIViewController *)viewController workingRangeSize:(NSInteger)workingRangeSize NS_DESIGNATED_INITIALIZER; diff --git a/Source/IGListAdapter.m b/Source/IGListAdapter.m index ce63e29c5..47c6d0191 100644 --- a/Source/IGListAdapter.m +++ b/Source/IGListAdapter.m @@ -34,14 +34,14 @@ - (void)dealloc { #pragma mark - Init -- (instancetype)initWithUpdater:(id )updatingDelegate +- (instancetype)initWithUpdater:(id )updater viewController:(UIViewController *)viewController workingRangeSize:(NSInteger)workingRangeSize { IGAssertMainThread(); - IGParameterAssert(updatingDelegate); + IGParameterAssert(updater); if (self = [super init]) { - NSPointerFunctions *keyFunctions = [updatingDelegate objectLookupPointerFunctions]; + NSPointerFunctions *keyFunctions = [updater objectLookupPointerFunctions]; NSPointerFunctions *valueFunctions = [NSPointerFunctions pointerFunctionsWithOptions:NSPointerFunctionsStrongMemory]; NSMapTable *table = [[NSMapTable alloc] initWithKeyPointerFunctions:keyFunctions valuePointerFunctions:valueFunctions capacity:0]; _sectionMap = [[IGListSectionMap alloc] initWithMapTable:table]; @@ -52,7 +52,7 @@ - (instancetype)initWithUpdater:(id )updatingDelegate _cellSectionControllerMap = [NSMapTable mapTableWithKeyOptions:NSMapTableObjectPointerPersonality | NSMapTableStrongMemory valueOptions:NSMapTableStrongMemory]; - _updatingDelegate = updatingDelegate; + _updater = updater; _viewController = viewController; } return self; @@ -259,7 +259,7 @@ - (void)performUpdatesAnimated:(BOOL)animated completion:(IGListUpdaterCompletio NSArray *newItems = [[dataSource objectsForListAdapter:self] copy]; __weak __typeof__(self) weakSelf = self; - [self.updatingDelegate performUpdateWithCollectionView:collectionView + [self.updater performUpdateWithCollectionView:collectionView fromObjects:fromObjects toObjects:newItems animated:animated @@ -294,7 +294,7 @@ - (void)reloadDataWithCompletion:(nullable IGListUpdaterCompletion)completion { NSArray *newItems = [[dataSource objectsForListAdapter:self] copy]; __weak __typeof__(self) weakSelf = self; - [self.updatingDelegate reloadDataWithCollectionView:collectionView reloadUpdateBlock:^{ + [self.updater reloadDataWithCollectionView:collectionView reloadUpdateBlock:^{ // purge all section controllers from the item map so that they are regenerated [weakSelf.sectionMap reset]; [weakSelf updateObjects:newItems dataSource:dataSource]; @@ -329,7 +329,7 @@ - (void)reloadObjects:(NSArray *)objects { UICollectionView *collectionView = self.collectionView; IGAssert(collectionView != nil, @"Tried to reload the adapter without a collection view"); - [self.updatingDelegate reloadCollectionView:collectionView sections:sections]; + [self.updater reloadCollectionView:collectionView sections:sections]; } @@ -917,7 +917,7 @@ - (void)reloadInSectionController:(IGListSectionController *) [self insertInSectionController:sectionController atIndexes:indexes]; } else { NSArray *indexPaths = [self indexPathsFromSectionController:sectionController indexes:indexes adjustForUpdateBlock:YES]; - [self.updatingDelegate reloadItemsInCollectionView:collectionView indexPaths:indexPaths]; + [self.updater reloadItemsInCollectionView:collectionView indexPaths:indexPaths]; } } @@ -933,7 +933,7 @@ - (void)insertInSectionController:(IGListSectionController *) } NSArray *indexPaths = [self indexPathsFromSectionController:sectionController indexes:indexes adjustForUpdateBlock:NO]; - [self.updatingDelegate insertItemsIntoCollectionView:collectionView indexPaths:indexPaths]; + [self.updater insertItemsIntoCollectionView:collectionView indexPaths:indexPaths]; } - (void)deleteInSectionController:(IGListSectionController *)sectionController atIndexes:(NSIndexSet *)indexes { @@ -948,7 +948,7 @@ - (void)deleteInSectionController:(IGListSectionController *) } NSArray *indexPaths = [self indexPathsFromSectionController:sectionController indexes:indexes adjustForUpdateBlock:YES]; - [self.updatingDelegate deleteItemsFromCollectionView:collectionView indexPaths:indexPaths]; + [self.updater deleteItemsFromCollectionView:collectionView indexPaths:indexPaths]; } - (void)reloadSectionController:(IGListSectionController *)sectionController { @@ -964,7 +964,7 @@ - (void)reloadSectionController:(IGListSectionController *)s } NSIndexSet *sections = [NSIndexSet indexSetWithIndex:section]; - [self.updatingDelegate reloadCollectionView:collectionView sections:sections]; + [self.updater reloadCollectionView:collectionView sections:sections]; } - (void)performBatchAnimated:(BOOL)animated updates:(void (^)())updates completion:(void (^)(BOOL))completion { @@ -974,7 +974,7 @@ - (void)performBatchAnimated:(BOOL)animated updates:(void (^)())updates completi IGAssert(collectionView != nil, @"Performing batch updates without a collection view."); __weak __typeof__(self) weakSelf = self; - [self.updatingDelegate performUpdateWithCollectionView:collectionView animated:animated itemUpdates:^{ + [self.updater performUpdateWithCollectionView:collectionView animated:animated itemUpdates:^{ weakSelf.isInUpdateBlock = YES; updates(); weakSelf.isInUpdateBlock = NO; diff --git a/Source/Internal/IGListAdapterInternal.h b/Source/Internal/IGListAdapterInternal.h index 35c0eb28d..f8cc11376 100644 --- a/Source/Internal/IGListAdapterInternal.h +++ b/Source/Internal/IGListAdapterInternal.h @@ -32,7 +32,7 @@ IGListCollectionContext __weak UICollectionView *_collectionView; } -@property (nonatomic, strong) id updatingDelegate; +@property (nonatomic, strong) id updater; @property (nonatomic, strong, readonly) IGListSectionMap *sectionMap; @property (nonatomic, strong, readonly) IGListDisplayHandler *displayHandler; diff --git a/Tests/IGListAdapterTests.m b/Tests/IGListAdapterTests.m index 437f71e28..0dbfe0b16 100644 --- a/Tests/IGListAdapterTests.m +++ b/Tests/IGListAdapterTests.m @@ -704,7 +704,7 @@ - (void)test_whenSectionControllerReloading_withEmptyIndexes_thatNoUpdatesHappen id mockDelegate = [OCMockObject mockForProtocol:@protocol(IGListUpdatingDelegate)]; [[mockDelegate reject] reloadItemsInCollectionView:[OCMArg any] indexPaths:[OCMArg any]]; - self.adapter.updatingDelegate = mockDelegate; + self.adapter.updater = mockDelegate; id sectionController = [self.adapter sectionControllerForObject:@1]; [self.adapter reloadInSectionController:sectionController atIndexes:[NSIndexSet new]]; @@ -718,7 +718,7 @@ - (void)test_whenSectionControllerDeleting_withEmptyIndexes_thatNoUpdatesHappen id mockDelegate = [OCMockObject mockForProtocol:@protocol(IGListUpdatingDelegate)]; [[mockDelegate reject] deleteItemsFromCollectionView:[OCMArg any] indexPaths:[OCMArg any]]; - self.adapter.updatingDelegate = mockDelegate; + self.adapter.updater = mockDelegate; id sectionController = [self.adapter sectionControllerForObject:@1]; [self.adapter deleteInSectionController:sectionController atIndexes:[NSIndexSet new]]; @@ -732,7 +732,7 @@ - (void)test_whenSectionControllerInserting_withEmptyIndexes_thatNoUpdatesHappen id mockDelegate = [OCMockObject mockForProtocol:@protocol(IGListUpdatingDelegate)]; [[mockDelegate reject] insertItemsIntoCollectionView:[OCMArg any] indexPaths:[OCMArg any]]; - self.adapter.updatingDelegate = mockDelegate; + self.adapter.updater = mockDelegate; id sectionController = [self.adapter sectionControllerForObject:@1]; [self.adapter insertInSectionController:sectionController atIndexes:[NSIndexSet new]]; @@ -746,7 +746,7 @@ - (void)test_whenReloading_withSectionControllerNotFound_thatNoUpdatesHappen { id mockDelegate = [OCMockObject mockForProtocol:@protocol(IGListUpdatingDelegate)]; [[mockDelegate reject] reloadCollectionView:[OCMArg any] sections:[OCMArg any]]; - self.adapter.updatingDelegate = mockDelegate; + self.adapter.updater = mockDelegate; id sectionController = [IGListSectionController new]; [self.adapter reloadSectionController:sectionController];