iOS - DrawRect性能问题

时间:2012-06-15 21:33:14

标签: ios uitableview core-graphics drawrect lag

我第一次使用-drawRect试图加速UITableView。但是,drawRect方法似乎在很大程度上减慢了表格。

请告诉我如何改进下面的drawRect方法以加快速度?

编辑---

在drawRect方法中,我正在向单元格视图写入两个NSStrings,两个UIImages以及两个NSStrings和一个UIImages的阴影。

上述图像之一是异步下载,然后调用setNeedsDisplay将UIImage绘制到屏幕上。我认为这最初可能是导致滞后的原因。

- (void) drawRect:(CGRect) rect {

    CGContextRef context = UIGraphicsGetCurrentContext();

    [[UIColor clearColor] set];

    CGContextFillRect(context, rect);

    CGContextSaveGState(context);
    CGContextSetShadow(context, CGSizeMake(1,1),1);
    //draw text here

    if (shouldDrawImage == YES) {

        CGContextDrawImage(context, CGRectMake(10, 10, 40, 40), self.image.CGImage);

    }

    CGContextDrawImage(context, CGRectMake(self.frame.size.width - 16, 0, 16, self.frame.size.height), [UIImage imageNamed:@"right_bar_including_holes"].CGImage);

    NSString *authorName = [[self.info objectForKey:@"user"] objectForKey:@"full_name"];

    [RGB(219, 240, 73) set];

    CGSize maximumLabelSize = CGSizeMake(self.frame.size.width - 10 - 55 - 16,9999);
    CGSize authorsize = [authorName sizeWithFont:[UIFont boldSystemFontOfSize:15]
                                     constrainedToSize:maximumLabelSize 
                                         lineBreakMode:UILineBreakModeWordWrap]; 
    [authorName drawInRect:CGRectMake(60, 10, self.frame.size.width - 60, authorsize.height) withFont:[UIFont boldSystemFontOfSize:15]];

    [RGB(249,249,249) set];

    NSString *description = [self.info objectForKey:@"description"];
    CGSize descriptionSize = [description sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:maximumLabelSize lineBreakMode:UILineBreakModeWordWrap];

    [description drawInRect:CGRectMake(60, authorsize.height + 15, descriptionSize.width, descriptionSize.height) withFont:[UIFont systemFontOfSize:14]];

    CGContextRestoreGState(context);

}

- (NSString *) reuseIdentifier {
    return NSStringFromClass([SlideCell class]);
}

- (void) updateCellInfo:(NSDictionary *)_info {
    [self setInfo:_info];

    UIImageView *iv = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
    [iv setImageWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[[self.info objectForKey:@"user"] objectForKey:@"avatar"]]] placeholderImage:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *_image) {
        dispatch_async(dispatch_get_main_queue(), ^{
            shouldDrawImage = YES;
            self.image = [self roundedImage:_image];
            [iv release];
            [self setNeedsDisplay];
        });

    } failure:nil];

    [self setNeedsDisplay];

    [self setSelectionStyle:UITableViewCellSelectionStyleNone];
}

3 个答案:

答案 0 :(得分:2)

是的 - 您在应用上运行了仪器的时间档案,准确地告诉您花了多少时间,在哪里。它会告诉你它是图像,字符串,阴影还是其他东西。

答案 1 :(得分:1)

您应该对该代码进行分析,然后首先查看图像是否存在问题。

我不确定AFNetworking库(您正在使用的)在异步下载图像时是如何工作的。

如果您知道图像是问题,我怀疑图像需要在UIImageView设置时重新调整。这可能是问题所在。您需要将要设置为UIImageView的UIImage重新缩放到UIIImageView的框架,这样就不会触发自动缩放。滚动时这很昂贵。

您收到图像并立即将代码发送到主线程。潜在的重新缩放可能在“引擎盖下”起作用。我会将该方法更改为:

UIImageView *iv = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, IMGSIZEX, IMGSIZEY)];
    [iv setImageWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[[self.info objectForKey:@"user"] objectForKey:@"avatar"]]] placeholderImage:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *_image) {
        //Note you have to implement rescaleToFitSize
        UIImage* rescaled = [_image rescaleToFitSize:iv.frame.size];
        dispatch_async(dispatch_get_main_queue(), ^{
            self.image = _image;
            [iv release];
            [self setNeedsDisplay];
        });

    } failure:^{
         //Handle failure! You create mem. leak on failure
         [iv release];
}];

作为旁注,您不会处理图像下载失败。你肯定应该。

答案 2 :(得分:1)

如果你正确使用它,股票UITableView就像它一样高效: 1.回收细胞(出队) 2.只要有可能就避免使用透明度(alpha混合会降低速度) 3.重用单元的配置不需要太多的处理时间。

我认为任何人都不能通过覆盖drawRect来显着提高Apple的代码......