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

fix(ios): listview performance optimization and bug fix #3572

Merged
merged 3 commits into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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