滚动时 UITableView 滞后
UITableView is laggy when scrolling
我有一个 UITableView,它在滚动过程中变得非常迟钝。
图像保存在 JSON 的数组中(在 viewDidLoad 中),我在 cellForRowAtIndexPath 中的图像代码是:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = @"UserDiscountsTableViewCell";
UserDiscountsTableViewCell *cell = (UserDiscountsTableViewCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"UserDiscountsTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.userDiscountNameLabel.text = [userDiscountName objectAtIndex:indexPath.row];
cell.userDiscountImages.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[userDiscountImages objectAtIndex:indexPath.row]]]];
return cell;
}
我正在使用自定义 UITableViewCell。当我删除带有 cell.userDiscountImages.image 的代码部分时,一切正常。
谁能告诉我滚动延迟的原因是什么?
您的 table 视图滞后,因为您在加载图像时正在主线程上执行网络代码。请参阅苹果文档:https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/index.html#//apple_ref/occ/clm/NSData/dataWithContentsOfURL:
这个开源库是处理异步图像加载的好方法:https://github.com/rs/SDWebImage
您自己回答了您的问题:如果您删除了设置图像的那条线,一切正常。这条线需要很多时间来处理并且你在主线程上完成它,你阻塞了 UI.
尝试使用 Grand Central Dispatch 将图像初始化发送到后台线程。初始化完成后,您需要返回主线程,然后才能进行 UI 更新。这看起来像这样:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage *img = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[userDiscountImages objectAtIndex:indexPath.row]]]];
dispatch_async(dispatch_get_main_queue(), ^{
UserDiscountsTableViewCell *discountCell = (UserDiscountsTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
discountCell.userDiscountImages.image = img
});
});
请注意,在初始化图像后,我没有直接在单元格上设置它,而是从 UITableView
取回它:这是因为在图像加载时,单元格可能已经用于在另一个 NSIndexPath
处显示另一个单元格。如果不这样做,最终可能会在错误的单元格中出现错误的图像。
我有一个 UITableView,它在滚动过程中变得非常迟钝。 图像保存在 JSON 的数组中(在 viewDidLoad 中),我在 cellForRowAtIndexPath 中的图像代码是:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = @"UserDiscountsTableViewCell";
UserDiscountsTableViewCell *cell = (UserDiscountsTableViewCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"UserDiscountsTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.userDiscountNameLabel.text = [userDiscountName objectAtIndex:indexPath.row];
cell.userDiscountImages.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[userDiscountImages objectAtIndex:indexPath.row]]]];
return cell;
}
我正在使用自定义 UITableViewCell。当我删除带有 cell.userDiscountImages.image 的代码部分时,一切正常。
谁能告诉我滚动延迟的原因是什么?
您的 table 视图滞后,因为您在加载图像时正在主线程上执行网络代码。请参阅苹果文档:https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/index.html#//apple_ref/occ/clm/NSData/dataWithContentsOfURL:
这个开源库是处理异步图像加载的好方法:https://github.com/rs/SDWebImage
您自己回答了您的问题:如果您删除了设置图像的那条线,一切正常。这条线需要很多时间来处理并且你在主线程上完成它,你阻塞了 UI.
尝试使用 Grand Central Dispatch 将图像初始化发送到后台线程。初始化完成后,您需要返回主线程,然后才能进行 UI 更新。这看起来像这样:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage *img = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[userDiscountImages objectAtIndex:indexPath.row]]]];
dispatch_async(dispatch_get_main_queue(), ^{
UserDiscountsTableViewCell *discountCell = (UserDiscountsTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
discountCell.userDiscountImages.image = img
});
});
请注意,在初始化图像后,我没有直接在单元格上设置它,而是从 UITableView
取回它:这是因为在图像加载时,单元格可能已经用于在另一个 NSIndexPath
处显示另一个单元格。如果不这样做,最终可能会在错误的单元格中出现错误的图像。