Before, I don't know why, when I reloadData
my tableVIew, it takes a very long time.
I have test Log
to prove, shows the slow is not because the network:
2016-12-29 14:50:20.958 Eee[1572:25220] lml-info-vc-test-net-began
2016-12-29 14:50:20.958 Eee[1572:25220] lml-info-vc-test-net-end
2016-12-29 14:50:20.972 Eee[1572:25220] lml-info-vc-test-net-animations-reloadData-bigin
2016-12-29 14:50:34.870 Eee[1572:25220] lml-info-vc-test-net-animations-reloadData-end
As we see, the net-began and net-end takes very little time.
But the reloadData-bigin and reloadData-end takes a long time, so I searched the SO, what did the reloadData
do? I want to know deeply, not simple answer, I searched always is simple answer, not analyse in depth.
My reloadData
code:
//[self.pre_tableView reloadData];
[UIView animateWithDuration:0 animations:^{
NSLog(@"lml-info-vc-test-net-animations-reloadData-bigin");
[self.pre_tableView reloadData];
NSLog(@"lml-info-vc-test-net-animations-reloadData-end");
} completion:^(BOOL finished) {
//Do something after that...
[_pre_tableView.mj_footer endRefreshing];
[_pre_tableView.mj_header endRefreshing];
}];
I use animation block, and in the completionHadler
to end the refreshing.
I also searched the apple docs for reloadData
In the Discussion:
Call this method to reload all the data that is used to construct the table, including cells, section headers and footers, index arrays, and so on. For efficiency, the table view redisplays only those rows that are visible. It adjusts offsets if the table shrinks as a result of the reload. The table view’s delegate or data source calls this method when it wants the table view to completely reload its data. It should not be called in the methods that insert or delete rows, especially within an animation block implemented with calls to beginUpdates and endUpdates.
Attention
With the attentive sentence:
It should not be called in the methods that insert or delete rows, especially within an animation block
Well! It means I should not in my UIView
's animateWithDuration
method to reloadData
, so I replace my code to below:
[self.pre_tableView reloadData];
[_pre_tableView.mj_footer endRefreshing];
[_pre_tableView.mj_header endRefreshing];
Now it is not slow any more. Very happy, I find the reason.
But, I just want to know why, why can not put reloadData
method in animation block ?
And it reloadData
did not fail, even takes a long time, in the animate block happens what? then it takes so many time here?
Edit -1
My additional code is below:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.pre_dataSource.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:info_TableIdentifier];
if (cell == nil) {
cell = [[LMLAgricultureTechCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:info_TableIdentifier];
}
//NSLog(@"lml-info-vc-test-cellSetModel-began");
((LMLAgricultureTechCell *)cell).model = self.pre_dataSource[indexPath.row];
//NSLog(@"lml-info-vc-test-cellSetModel-end");
((LMLAgricultureTechCell *)cell).indexPath = indexPath;
((LMLAgricultureTechCell *)cell).delegate = self;
((LMLAgricultureTechCell *)cell).photo_view.delegate = self;
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// >>>>>>>>>>>>>>>>>>>>> * cell自适应 * >>>>>>>>>>>>>>>>>>>>>>>>
id model;
model = self.pre_dataSource[indexPath.row];
return [self.pre_tableView cellHeightForIndexPath:indexPath model:model keyPath:@"model" cellClass:[LMLAgricultureTechCell class] contentViewWidth:[self cellContentViewWith]];
}
UIView.animateWithDuration...
methods can only animate values that areanimatable
. Although it sometimes feels like magic - it's not really...reloadData
is an async method that can not be handled by theanimate
block the be animated.If you want to animate the transition you can either use
insert/delete/moveRows
or use thetransitionWithView
method ofUIView
. This method would render the view off-screen completely as it will look after all the changes you put in it's block, than animate transit between the current state of the view and the newly rendered view. The animation itself depends on the options you deliver, and you probably want to useUIViewAnimationOptionsTransitionCrossDissolve
.