如何使滚动UITableView更顺畅?

时间:2011-09-13 10:40:46

标签: iphone objective-c performance cocoa-touch uitableview

我有一个包含约20个单元格的桌面视图,其中包含从网上下载的图像。

现在滚动时它会起伏不定,需要更加平滑。

我的方法是:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {

        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];

        for (id currentObject in topLevelObjects){
            if ([currentObject isKindOfClass:[UITableViewCell class]]){
                cell =  (CustomCell *) currentObject;
                break;
            }
        }
    }

    NSDictionary *article = [entriesArray objectAtIndex:[indexPath row]];
    NSString *title = [article objectForKey:@"title"];
    NSString *date = [article objectForKey:@"publishedDate"];
    NSString *dateEdited = [date substringToIndex:16];

    cell.nameLabel.text  = title;
    cell.dateLabel.text  = dateEdited;

    NSURL *myURL=[NSURL URLWithString:[self.picturesArray objectAtIndex:indexPath.row]]; 
    NSData *myData1 = [[NSData alloc] initWithContentsOfURL:myURL];
    UIImage *myImage = [[UIImage alloc] initWithData:myData1]; 

    cell.imageView.image = myImage;
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 2;

    return cell;
}

有什么建议吗?

6 个答案:

答案 0 :(得分:2)

有一些问题。首先,你有一些内存泄漏。 myData1和myImage已创建但未发布。

然而,我的猜测是,大的性能命中与你创建UIImage有关。将此移出此单元格请求方法。也许创建一个可以绘制的图像缓存。例如,将它们作为初始化方法中创建的静态UIImage对象。

我认为这将解决您的大部分性能问题。最后一个调整是从这个方法中删除你的for循环。也许创建一个NSDictionary,以便可以直接查找对象。

答案 1 :(得分:2)

您似乎没有在后台线程上运行网络请求,这是您需要做的事情。不仅从性能角度而且从稳定性角度来看。如果您发出网络请求的服务器已关闭,会发生什么?我不确定initWithContentsOfURL如何处理失败但你的代码似乎没有检查该方法的失败,所以看起来你的程序会因网络问题而崩溃。

在后台线程上实现fetch不会导致主线程被阻塞,允许你的UITableView更加无缝地滚动,但是这样做的权衡是桌面视图图像在等待时可能会空白一会儿后台线程来完成网络请求。

答案 2 :(得分:0)

您不应该在主事件循环中下载图像文件。

尝试使用像SDWebImage这样的背景下载器。

答案 3 :(得分:0)

这是加载自定义单元格的方法

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
cell = [CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIndetifier];
    }

    NSDictionary *article = [entriesArray objectAtIndex:[indexPath row]];
    NSString *title = [article objectForKey:@"title"];
    NSString *date = [article objectForKey:@"publishedDate"];
    NSString *dateEdited = [date substringToIndex:16];

    cell.nameLabel.text  = title;
    cell.dateLabel.text  = dateEdited;

    NSURL *myURL=[NSURL URLWithString:[self.picturesArray objectAtIndex:indexPath.row]]; 
    NSData *myData1 = [[NSData alloc] initWithContentsOfURL:myURL] autorelease];
    UIImage *myImage = [[UIImage alloc] initWithData:myData1] autorelease]; 

    cell.imageView.image = myImage;
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 2;

    return [cell autorelease];
}

答案 4 :(得分:0)

我要检查的第一个地方(也是一个容易错过的地方)是确保您的单元格的重用标识符在CustomCell.xib文件中正确设置(在您的情况下为“Cell”)。

示例:

enter image description here

创建您的手机。假设您有一个名为CustomCell.xib的笔尖,您应该在视图控制器中创建一个IBOutlet:

@property(nonatomic,retain)IBOutlet UITableViewCell * customCell;

然后在CustomCell笔尖中,将文件所有者设置为视图控制器,并将单元格连接到文件所有者自定义单元格插座。

要创建单元格,请使用以下代码:

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if(cell == nil)
    {
        [[NSBundle mainBundle] loadNibNamed: @"CustomCell" owner: self options: nil];
        cell = self.customCell;
        self.customCell = nil;
    }
    // Customise your cell here
    return cell;    
}

答案 5 :(得分:0)

您需要懒洋洋地加载图片。这意味着将它们加载到另一个线程中Apple有excellent sample code that demonstrates this