Ios UITableView滚动显示不良性能
我的tableviewcontroller有一个很大的性能问题。卷轴很慢。我已经在didSelectRowAtIndexPath方法上创建了一个NSLOG,并且我意识到我所做的每一个滚动都会调用它。应该是这样的吗 我对这个表进行了搜索,我有一些逻辑,因为数据取决于json响应。您可以在此处检查此方法:Ios UITableView滚动显示不良性能,ios,uitableview,Ios,Uitableview,我的tableviewcontroller有一个很大的性能问题。卷轴很慢。我已经在didSelectRowAtIndexPath方法上创建了一个NSLOG,并且我意识到我所做的每一个滚动都会调用它。应该是这样的吗 我对这个表进行了搜索,我有一些逻辑,因为数据取决于json响应。您可以在此处检查此方法: - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)index
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//NSLog(@" scroll");
// Configure the cell...
static NSString *CellIdentifier = @"contactCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
UILabel *nameLabel = (UILabel *)[cell viewWithTag:1];
UILabel *workPlaceLabel = (UILabel *)[cell viewWithTag:2];
if(searching)
{
//NSLog(@" copyListOfItems: %@",copyListOfItems);
NSString*lastName=[[[copyListOfItems objectAtIndex:indexPath.row]objectForKey:@"Contact"]objectForKey:@"lastname"];
if(lastName==nil)
{
lastName=@" ";
}
NSString*firstName=[[[copyListOfItems objectAtIndex:indexPath.row]objectForKey:@"Contact"]objectForKey:@"firstname"];
if(firstName==nil)
{
NSArray*phonesArray=[[[copyListOfItems objectAtIndex:indexPath.row]objectForKey:@"Contact"]objectForKey:@"phone"];
NSLog(@"NUMERO TELEFONE %d",[phonesArray count]);
if([phonesArray count]>0)
{
NSString*phoneNumber=[[[copyListOfItems objectAtIndex:indexPath.row]objectForKey:@"Contact"] objectForKey:@"Phone"];
nameLabel.text=phoneNumber;
}else{
nameLabel.text=[[[copyListOfItems objectAtIndex:indexPath.row]objectForKey:@"Contact"] objectForKey:@"Current"];
workPlaceLabel.text=@"";
}
}else{
NSString *stringName= [NSString stringWithFormat:@"%@ %@", firstName, lastName];
nameLabel.text=stringName;
workPlaceLabel.text=[[[copyListOfItems objectAtIndex:indexPath.row]objectForKey:@"Contact"] objectForKey:@"Current"];
}
}
else {
//NSLog(@" _contactsArray: %@",_contactsArray);
NSString*lastName=[[[_contactsArray objectAtIndex:indexPath.row]objectForKey:@"Contact"] objectForKey:@"Lastname"];
if(lastName==nil)
{
lastName=@" ";
}
NSString*firstName=[[[_contactsArray objectAtIndex:indexPath.row]objectForKey:@"Contact"] objectForKey:@"Firstname"];
if(firstName==nil)
{
NSArray*phonesArray=[[[_contactsArray objectAtIndex:indexPath.row]objectForKey:@"Contact"] objectForKey:@"Phone"];
//NSLog(@"NUMERO TELEFONE %d",[phonesArray count]);
if([phonesArray count]>0)
{
NSString*phoneNumber=[[[[_contactsArray objectAtIndex:indexPath.row]objectForKey:@"phone"] objectAtIndex:0]objectForKey:@"phonenumber"];
nameLabel.text=phoneNumber;
}else{
nameLabel.text=[[[_contactsArray objectAtIndex:indexPath.row]objectForKey:@"Contact"] objectForKey:@"Current"];
workPlaceLabel.text=@"";
}
}else{
NSString *stringName= [NSString stringWithFormat:@"%@ %@", firstName, lastName];
nameLabel.text=stringName;
if([[[_contactsArray objectAtIndex:indexPath.row]objectForKey:@"Contact"] objectForKey:@"Current"])
{
workPlaceLabel.text=[[[_contactsArray objectAtIndex:indexPath.row]objectForKey:@"Contact"] objectForKey:@"Current"];
}
}
}
// Configure the cell...
return cell;
}
为每个出现的单元格调用,因此如果您将逻辑排除在该循环之外会更好,因为当用户滚动时,它将被多次调用。您可以在该循环之外设置数组,并仅替换此方法中的值
为出现的每个单元格调用,因此如果您将逻辑排除在该循环之外会更好,因为当用户滚动时,它将被多次调用。您可以在该循环之外设置数组,只需替换此方法中的值即可。此方法中有许多不必要的调用可以从代码中删除。所有那些重复拨打的联系电话都需要时间才能完成,而您只需拨打一次。与if语句的第一个分支一样,您有如下调用:
NSString*lastName=[[[copyListOfItems objectAtIndex:indexPath.row]objectForKey:@"Contact"]objectForKey:@"lastname"];
NSString*firstName=[[[copyListOfItems objectAtIndex:indexPath.row]objectForKey:@"Contact"]objectForKey:@"firstname"];
NSArray*phonesArray=[[[copyListOfItems objectAtIndex:indexPath.row]objectForKey:@"Contact"]objectForKey:@"phone"];
您可以通过执行以下操作压缩这些调用:
id contact = [[copyListOfItems objectAtIndex:indexPath.row]objectForKey:@"Contact"];
NSString *lastName=[contact objectForKey:@"lastname"];
NSString *firstName=[contact objectForKey:@"firstname"];
NSArray *phonesArray=[contact objectForKey:@"phone"];
Contact *contact = (Contact *)[[copyListOfItems objectAtIndex:indexPath.row]objectForKey:@"Contact"];
NSString *lastName = contact.lastName;
NSString *firstName = contact.firstName;
NSArray *phonesArray = contact.phone;
理想情况下,您可以拥有自己的类,该类将这些项作为属性,这样您就可以执行以下操作:
id contact = [[copyListOfItems objectAtIndex:indexPath.row]objectForKey:@"Contact"];
NSString *lastName=[contact objectForKey:@"lastname"];
NSString *firstName=[contact objectForKey:@"firstname"];
NSArray *phonesArray=[contact objectForKey:@"phone"];
Contact *contact = (Contact *)[[copyListOfItems objectAtIndex:indexPath.row]objectForKey:@"Contact"];
NSString *lastName = contact.lastName;
NSString *firstName = contact.firstName;
NSArray *phonesArray = contact.phone;
编辑:如何进行异步图像加载
下面是我过去如何使用占位符图像异步加载图像的。我使用的单元格是我编写的一个自定义类,但它应该能让您了解如何使用它
// Setup the image view
UIImageView* imageView = cell.imageView;
imageView.image = [UIImage imageNamed:@"Loading.png"];
// Load the image asynchronously
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
// Here you will want to make a call to your web server to get the image
// and store it in a UIImage named image
UIImage *image = // your code to get the image from the server
// Only update if the cell is still on the screen
if ([[tableView indexPathsForVisibleRows] containsObject:indexPath]) {
// Have to update UI elements on the main thread
dispatch_sync(dispatch_get_main_queue(), ^{
[[cell imageView] setImage:image];
[cell setNeedsLayout];
});
}
});
这里面有很多不必要的调用可以从代码中删除。所有那些重复拨打的联系电话都需要时间才能完成,而您只需拨打一次。与if语句的第一个分支一样,您有如下调用:
NSString*lastName=[[[copyListOfItems objectAtIndex:indexPath.row]objectForKey:@"Contact"]objectForKey:@"lastname"];
NSString*firstName=[[[copyListOfItems objectAtIndex:indexPath.row]objectForKey:@"Contact"]objectForKey:@"firstname"];
NSArray*phonesArray=[[[copyListOfItems objectAtIndex:indexPath.row]objectForKey:@"Contact"]objectForKey:@"phone"];
您可以通过执行以下操作压缩这些调用:
id contact = [[copyListOfItems objectAtIndex:indexPath.row]objectForKey:@"Contact"];
NSString *lastName=[contact objectForKey:@"lastname"];
NSString *firstName=[contact objectForKey:@"firstname"];
NSArray *phonesArray=[contact objectForKey:@"phone"];
Contact *contact = (Contact *)[[copyListOfItems objectAtIndex:indexPath.row]objectForKey:@"Contact"];
NSString *lastName = contact.lastName;
NSString *firstName = contact.firstName;
NSArray *phonesArray = contact.phone;
理想情况下,您可以拥有自己的类,该类将这些项作为属性,这样您就可以执行以下操作:
id contact = [[copyListOfItems objectAtIndex:indexPath.row]objectForKey:@"Contact"];
NSString *lastName=[contact objectForKey:@"lastname"];
NSString *firstName=[contact objectForKey:@"firstname"];
NSArray *phonesArray=[contact objectForKey:@"phone"];
Contact *contact = (Contact *)[[copyListOfItems objectAtIndex:indexPath.row]objectForKey:@"Contact"];
NSString *lastName = contact.lastName;
NSString *firstName = contact.firstName;
NSArray *phonesArray = contact.phone;
编辑:如何进行异步图像加载
下面是我过去如何使用占位符图像异步加载图像的。我使用的单元格是我编写的一个自定义类,但它应该能让您了解如何使用它
// Setup the image view
UIImageView* imageView = cell.imageView;
imageView.image = [UIImage imageNamed:@"Loading.png"];
// Load the image asynchronously
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
// Here you will want to make a call to your web server to get the image
// and store it in a UIImage named image
UIImage *image = // your code to get the image from the server
// Only update if the cell is still on the screen
if ([[tableView indexPathsForVisibleRows] containsObject:indexPath]) {
// Have to update UI elements on the main thread
dispatch_sync(dispatch_get_main_queue(), ^{
[[cell imageView] setImage:image];
[cell setNeedsLayout];
});
}
});
令人惊叹的。我已经用另一种方法进行了逻辑和验证。现在我会照你说的做,但我还有一个问题。现在我必须把化身放在牢房里。阿凡达来自一个NSURL。这完全是对我的应用程序收费过高。您有任何ideia吗?您需要设置一个占位符映像,并使用调度队列异步加载映像。我将编辑上面的答案和一些如何做的伪代码。真棒。我已经用另一种方法进行了逻辑和验证。现在我会照你说的做,但我还有一个问题。现在我必须把化身放在牢房里。阿凡达来自一个NSURL。这完全是对我的应用程序收费过高。您有任何ideia吗?您需要设置一个占位符映像,并使用调度队列异步加载映像。我将用一些伪代码编辑上面的答案。