Skip to content

Commit

Permalink
fix(ios): listview performance optimization and bug fix (#3572)
Browse files Browse the repository at this point in the history
* fix(ios): listview performance optimization and bug fix p1

* fix(ios): listview performance optimization and bug fix p2

* fix(ios): fix listview amendLayoutBeforeMount bug
  • Loading branch information
wwwcg authored Oct 30, 2023
1 parent e3b2171 commit d8653ca
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 12 deletions.
4 changes: 2 additions & 2 deletions framework/examples/ios-demo/podfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ install! 'cocoapods',
:deterministic_uuids => false,
:generate_multiple_pod_projects => true

#use_frameworks! :linkage => :static # 静态库framework格式
#ENV["use_frameworks"] = "true" # for hippy when set use_frameworks!
use_frameworks! :linkage => :static # 静态库framework格式
ENV["use_frameworks"] = "true" # for hippy when set use_frameworks!

workspace 'HippyDemo.xcworkspace'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,17 @@ - (void)applyDiff:(NativeRenderBaseListViewDataSource *)another
completion(YES);
return;
}
// NSArray<NSInvocation *> *batchUpdateInvocations = [self cellViewChangeInvocation:another context:context forCollectionView:view];

// Attention, we do partial reload only when 1 item change!
// because differential refreshing causes the display event of the cell to not trigger,
// So we limit this to when only one cell is updated
if (context.allChangedItems.count > 1) {
[view reloadData];
completion(YES);
return;
}

// The following logic is not perfect and needs to be further refined
NSMutableArray<NSInvocation *> *batchUpdate = [NSMutableArray arrayWithCapacity:8];
[self cellDiffFromAnother:another
sectionStartAt:0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,15 @@ NS_ASSUME_NONNULL_BEGIN
- (NSSet<__kindof HippyShadowView *> *)deletedItems;
- (NSHashTable<__kindof HippyShadowView *> *)movedItems;

/// Clear all items recorded.
- (void)clear;

/// Whether has changed item.
- (BOOL)hasChanges;

/// Get all chaned items.
- (NSSet<HippyShadowView *> *)allChangedItems;

@end

@interface NativeRenderObjectWaterfall : HippyShadowView<NativeRenderObjectWaterfallItemFrameChangedProtocol>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,8 @@ - (void)appendMovedItem:(__kindof HippyShadowView *)objectView {
}

- (void)appendFrameChangedItem:(__kindof HippyShadowView *)objectView {
if (![_addedItems containsObject:objectView]) {
[_frameChangedItems addObject:objectView];
}
// _frameChangedItems may be also in other addedItems/movedItems
[_frameChangedItems addObject:objectView];
}

- (NSSet<__kindof HippyShadowView *> *)deletedItems {
Expand All @@ -94,6 +93,20 @@ - (void)appendFrameChangedItem:(__kindof HippyShadowView *)objectView {
return [_frameChangedItems copy];
}

- (BOOL)hasChanges {
return _addedItems.count != 0 || _deletedItems.count != 0 ||
_movedItems.count != 0 || _frameChangedItems.count != 0;
}

- (NSSet<HippyShadowView *> *)allChangedItems {
NSMutableSet *allChanges = [NSMutableSet set];
[allChanges addObjectsFromArray:_addedItems.allObjects];
[allChanges addObjectsFromArray:_deletedItems.allObjects];
[allChanges addObjectsFromArray:_movedItems.allObjects];
[allChanges addObjectsFromArray:_frameChangedItems.allObjects];
return allChanges;
}

- (void)clear {
[_deletedItems removeAllObjects];
[_addedItems removeAllObjects];
Expand Down Expand Up @@ -162,27 +175,28 @@ - (void)itemFrameChanged:(__kindof NativeRenderObjectWaterfallItem *)item {
}

- (void)amendLayoutBeforeMount:(NSMutableSet<NativeRenderApplierBlock> *)blocks {
if ([self isPropagationDirty:NativeRenderUpdateLifecycleLayoutDirtied]) {
__weak NativeRenderObjectWaterfall *weakSelf = self;
if ([self isPropagationDirty:NativeRenderUpdateLifecycleLayoutDirtied] &&
_itemChangeContext.hasChanges) {
WaterfallItemChangeContext *context = [_itemChangeContext copy];
NSArray<HippyShadowView *> *dataSource = [self.subcomponents copy];
__weak __typeof(self)weakSelf = self;
NativeRenderApplierBlock block = ^void(NSDictionary<NSNumber *, UIView *> *viewRegistry) {
NativeRenderObjectWaterfall *strongSelf = weakSelf;
__strong __typeof(weakSelf)strongSelf = weakSelf;
if (!strongSelf) {
return;
}
NativeRenderWaterfallView *view = (NativeRenderWaterfallView *)[viewRegistry objectForKey:[strongSelf hippyTag]];
HippyAssert([view isKindOfClass:[NativeRenderWaterfallView class]], @"view must be kind of NativeRenderWaterfallView");
if ([view isKindOfClass:[NativeRenderWaterfallView class]]) {
view.dirtyContent = YES;
view.changeContext = [context copy];
view.changeContext = context;
[view pushDataSource:dataSource];
}
};
[blocks addObject:block];
[_itemChangeContext clear];
}
[super amendLayoutBeforeMount:blocks];
[_itemChangeContext clear];
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ - (instancetype)initWithFrame:(CGRect)frame {
_scrollEventThrottle = 100.f;
_weakItemMap = [NSMapTable strongToWeakObjectsMapTable];
_cachedItems = [NSMutableDictionary dictionaryWithCapacity:32];
_dataSourcePool = [NSMutableArray arrayWithCapacity:8];
_dataSourcePool = [NSMutableArray array];
_dataSourceSem = dispatch_semaphore_create(1);
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMemoryWarning) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
[self initCollectionView];
Expand Down

0 comments on commit d8653ca

Please sign in to comment.