Ios UITableView滚动显示不良性能

Ios UITableView滚动显示不良性能,ios,uitableview,Ios,Uitableview,我的tableviewcontroller有一个很大的性能问题。卷轴很慢。我已经在didSelectRowAtIndexPath方法上创建了一个NSLOG,并且我意识到我所做的每一个滚动都会调用它。应该是这样的吗 我对这个表进行了搜索,我有一些逻辑,因为数据取决于json响应。您可以在此处检查此方法: - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)index

我的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;
}
为每个出现的单元格调用,因此如果您将逻辑排除在该循环之外会更好,因为当用户滚动时,它将被多次调用。您可以在该循环之外设置数组,并仅替换此方法中的值


为出现的每个单元格调用,因此如果您将逻辑排除在该循环之外会更好,因为当用户滚动时,它将被多次调用。您可以在该循环之外设置数组,只需替换此方法中的值即可。

此方法中有许多不必要的调用可以从代码中删除。所有那些重复拨打的联系电话都需要时间才能完成,而您只需拨打一次。与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吗?您需要设置一个占位符映像,并使用调度队列异步加载映像。我将用一些伪代码编辑上面的答案。