我的tableviewcontroller上遇到了很大的性能问题。滚动很慢。我在didSelectRowAtIndexPath方法上创建了一个NSLOG,我意识到每次滚动都会调用它。它应该是那样的?
我在这个表上搜索了,我有一些逻辑,因为数据取决于json响应。您可以在此处查看此方法:
- (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;
}
答案 0 :(得分:2)
有很多不必要的调用可以从你的代码中删除。所有那些获得重复联系的电话都需要时间才能完成。就像你在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;
编辑:如何进行异步图像加载
以下是我过去使用占位符图像异步加载图像的方法。我使用的单元格是我写的一个自定义类,但它应该让你知道如何去做。
// 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];
});
}
});
答案 1 :(得分:1)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
对于出现的每个单元格都会调用,所以如果你将逻辑保持在这个循环之外会更好,因为当用户滚动时你会被调用多次,你可以将你的数组设置在这个循环之外,只需要替换这个方法中的值