1

here is my problem: My UITableViewController lags when I scroll it. It has about 60 custom cells. However, on the simulator it works without any lags. Here is my code: CustomCell.m

#import "CustomCell.h"

@implementation CustomCell

@synthesize nameLabel,costLabel,giftPicture;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code


        nameLabel = [[UILabel alloc]init];
        nameLabel.textAlignment = UITextAlignmentLeft;
        nameLabel.textColor = [UIColor colorWithRed:25/256.0 green:98/256.0       blue:52/256.0 alpha:1.0];
        costLabel = [[UILabel alloc]init];
        costLabel.textAlignment = UITextAlignmentLeft;


        giftPicture = [[UIImageView alloc]init];

        [self.contentView addSubview:nameLabel];
        [self.contentView addSubview:costLabel];
        [self.contentView addSubview:giftPicture];

        costLabel.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"background4"]];
        nameLabel.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"background4"]];
    }
    return self;
}
- (void)layoutSubviews {
    [super layoutSubviews];

    CGRect contentRect = self.contentView.bounds;
    CGFloat boundsX = contentRect.origin.x;
    CGRect frame;
    frame= CGRectMake(boundsX+10,10, 50, 50);
    giftPicture.frame = frame;

    frame= CGRectMake(boundsX+70 ,10, 350, 25);
    nameLabel.frame = frame;

    frame= CGRectMake(boundsX+70 ,40, 350, 18);
    costLabel.frame = frame;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

@end

List.m

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [array1 count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[CustomCell alloc] initWithFrame:CGRectZero];
    }

    // Configure the cell...


    NSString *cellValue = [array1 objectAtIndex:indexPath.row];
    //cell.textLabel.text = cellValue; // загаловок клетки
    [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; // сделал чтобы клетка была со стрелочкой

    cell.nameLabel.text = cellValue;

    NSDictionary  *mainDictionary = [[NSDictionary alloc]init];
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSArray *languages = [defaults objectForKey:@"AppleLanguages"];
    NSString *currentLanguage = [languages objectAtIndex:0];
    if([currentLanguage isEqualToString:@"en"])
    {
        mainDictionary = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"animals" ofType:@"txt"]];
    }
    NSEnumerator *enumerator = [mainDictionary objectEnumerator];
    id returnValue;

    while ((returnValue = [enumerator nextObject]))
    {

        if([cell.nameLabel.text isEqualToString:[returnValue valueForKey:@"name"]] )
        {

            cell.animalPicture.image = [UIImage imageNamed:[returnValue valueForKey:@"icon"]];
            cell.costLabel.text = [NSString stringWithFormat:@"$%@ - $%@",[returnValue valueForKey:@"minAge"],[returnValue valueForKey:@"maxAge"]];

        }
    }
    return cell;

}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 75;
}
@end

I tried to make custom cells empty (remove labels and images), just because of curious, but it didn't change anything. Could you tell me please, what I should check to fix these lags? Thanks!

SmartTree
  • 1,381
  • 3
  • 21
  • 40
  • I'm not sure, but it may have something to do with your `CustomCell` class; each cell contains multiple views and this could be causing the lag in scrolling. – sooper Feb 15 '12 at 02:20

3 Answers3

4

When dealing with performance issues in iOS apps trust the device, not the simulator. I've seen performance go both ways (sometimes better on simulator, sometimes better on the device). Remembering to test on the device will save you lots of time in the long run.

The lagging scrolling is most likely the result of the scrolling code being blocked by image processing or other network activity.

My personal preference for debugging these situations is to start with an empty table view. This should scroll smoothly even with thousands of cells. Then add your tableView contents back in one-by-one and pay attention to when the scrolling starts to lag.

Apple's Lazy Table Images sample code could help.

SundayMonday
  • 19,147
  • 29
  • 100
  • 154
4

You're doing a lot of initialisation in the -cellForRowAtIndexPath method with UIImages for every table cell. You should probably only do this once and cache the images.

cgull
  • 1,407
  • 1
  • 11
  • 18
4

Yeah thats just a TON of work to be doing for each table cell I think (also never never never trust the simulator for performance, it means nothing in relation to how things will behave on the device). You should try and use instruments to pinpoint exactly whats taking time but if I had to look at that I would say:

NSDictionary  *mainDictionary = [[NSDictionary alloc]init];

Just for starters this a) seems pointless because of this next line and b) looks like you are leaking this.

    mainDictionary = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"animals" ofType:@"txt"]];

Loading this file in every time cannot be stellar for performance, you should bring this data in once to like your view controller instead of every time you fill out a cell.

NSEnumerator *enumerator = [mainDictionary objectEnumerator];
id returnValue;

while ((returnValue = [enumerator nextObject]))
{

    if([cell.nameLabel.text isEqualToString:[returnValue valueForKey:@"name"]] )
    {

This whole chunk here, I would rework. This is to be blunt, using an NSDictionary wrong. A dictionary contains a Key and a Value, you shouldn't have to scan through the whole thing yourself with an enumerator to find the value you want by doing string comparisons, you should be using something like

[mainDictonary objectForKey:@"thingYouWant"];

doing what you said is like 60 complete enumerations of the dictionary and string comparisons can't be good for table performance and isn't necessary.

That would be the stuff I work check for performance first and then rework as needed, I'm willing to bet your performance issues are contained in those chunks.

  • Thank you very much for all your advices! Yes, I should work a lot with this code and remove all the "bad things". – SmartTree Feb 15 '12 at 09:16
  • Yeah, the main reason of lagging was that I was loading file every time creating a cell. Now I do it only once and tableView doesn't lag at all! Thank you very much! – SmartTree Feb 15 '12 at 15:24