内存警告,滚动视图和超过5000个自定义uiviews

时间:2012-08-21 08:53:11

标签: ios xcode memory

我需要帮助。

我在内部使用uiscrollview自定义uitableviewcell,我遍历一个nsarray并使用addsubview:方法添加自定义uiviews(只是继承drawrect:并自定义绘图)到我的scrollview,我每隔一秒刷新它就会给我一个内存警告并崩溃我的应用程序。我的项目是ARC,我不能打电话给发布。我认为这不是最佳解决方案。

感谢。

5 个答案:

答案 0 :(得分:2)

简单。不显示5000个视图,或仅创建/保留必须存在的视图。

清除不可见的内容 - 或者 - 如果它们同时全部可见,请使用不同的方法进行渲染。

答案 1 :(得分:1)

对Justin的回答有所改进,如果有一个数据列表,那么你最好去研究一下UITableView的工作原理。

如果您正在考虑构建游戏并在屏幕上同时拥有许多小图形,那么最好使用像Cocos2d或Sparrow这样的主要2D渲染库。

这些是你可以实现Justin的想法的两种方式,前者只在每行使用时绘制(换言之,保留在内存中)。后者是为处理大量较小的图像而构建的,通过自定义绘制程序可以更好地处理大量图形。

答案 2 :(得分:1)

最后,我使用我的第二种方法(自定义绘制单个UIView并将其添加到我的scrollview),感谢所有人的帮助。

答案 3 :(得分:0)

如果只是在几次刷新后崩溃,这意味着你可能有内存泄漏。

有可能你正在使用一些CG的东西。核心图形的东西不是由ARC维护的,你需要做CG发布。您可以通过添加任何缺少的版本来解决此问题,或者如果您没有在后台线程中执行图形处理,则通常可以使用UI等效项。

答案 4 :(得分:0)

是的戈登,我使用很多CG的东西来绘制我的自定义视图,但没有什么特别的,这是我的自定义UIView(ITPieceBlock)的绘图代码:

- (void)drawRect:(CGRect)rect { 
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(ctx, 1.00);

    CGContextSetRGBFillColor(ctx, 0.10, 0.10, 0.10, 1.0);
    CGContextFillRect(ctx, rect);




    if(self.status == 0)
        CGContextSetRGBFillColor(ctx, 0.5, 0.5, 1.00, 1.0);
    else
        CGContextSetRGBFillColor(ctx, 0.25, 0.25, 1.00, 1.0);

    CGContextFillRect(ctx, rect);
    CGContextSetRGBStrokeColor(ctx, 0.25, 0.25, 0.25, 1.0);
    CGContextStrokeRect(ctx, rect);

    [super drawRect:rect];
}

以及将此视图添加到我的UISCrollView的方法:

- (void)processPieces:(NSString *)pieces withCount:(double)pieceCount{
    static int i, j, k;
    static NSData *buffer;

    static int offsetX = 10;
    static int offsetY = 10;
    static int blockW = 5;
    static int blockH = 5;
    static int x;
    static int y;
    CGRect rect = _scrollView.frame;

    [_piecesArray removeAllObjects];

    buffer = [NSData dataWithBase64EncodedString:pieces];

    unsigned char* r = (unsigned char*)[buffer bytes];
    for (i=1; i<=[buffer length]; i++){
        j = (int) r[i];
        for (k=1; k<=8; k++){
            if (pieceCount == 8)
                break;
            if ((j & 0x80) != 0){
                [_piecesArray addObject:[NSNumber numberWithInt:1]];
            } else {
                [_piecesArray addObject:[NSNumber numberWithInt:0]];
            }

            j = j << 1;
            pieceCount--;
        }
    }

    x = offsetX;
    y = offsetY;

    if ([_piecesArray count] != 0)
        for (int i = 0; i< [_piecesArray count]; i++){
            if (i != 0) {
                if ((x + blockW) < rect.size.width - offsetX)
                    x += blockW;
                else {
                    x = offsetX;
                    y += blockH;
                }
            }

            ITPieceBlock * pieceBlock = [[ITPieceBlock alloc] initWithFrame:CGRectMake(x, y, blockW, blockH)];
            [pieceBlock setFrame:CGRectMake(x, y, blockW, blockH)];

            if ([[_piecesArray objectAtIndex:i] intValue] == 0)
                pieceBlock.status = 0;
            else
                pieceBlock.status = 1;

            [_scrollView addSubview:pieceBlock];
        }
    _scrollView.contentSize = CGSizeMake(280, y);
    [_scrollView flashScrollIndicators];
}