1

我需要帮助。

我有自定义的 uitableviewcell,里面有 uiscrollview,我遍历一个 nsarray 并使用 addsubview: 方法将自定义 uiviews(只是子类化 drawrect: 并进行自定义绘图)添加到我的滚动视图中,我每秒刷新一次,它给我一个内存警告并让我崩溃应用程序。我的项目是ARC,我不能调用release。我认为这不是最好的解决方案。

谢谢。

4

5 回答 5

2

简单的。不要显示 5000 个视图,或者只创建/保留您必须呈现的视图。

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

于 2012-08-21T10:12:59.813 回答
1

贾斯汀的答案的改进,如果有一个数据列表,那么你最好看看 UITableView 是如何工作的。

如果您正在考虑构建一个游戏并同时在屏幕上显示许多小图形,那么您最好使用 Cocos2d 或 Sparrow 等主要的 2d 渲染库。

这些是您可以实现贾斯汀想法的几种方法,前者仅在使用每一行时绘制(换句话说,保留在内存中)。后者是为处理大量较小的图像而构建的,并且通过执行自定义绘制例程在处理大量图形时表现更好。

于 2012-08-21T11:02:04.723 回答
1

最后,我使用我的第二种方法(自定义绘制单个 UIView 并将其添加到我的滚动视图)感谢大家的帮助。

于 2012-08-21T18:28:31.730 回答
0

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

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

于 2012-08-21T10:06:54.097 回答
0

是的,Gordon,我使用了很多 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];
}
于 2012-08-21T16:12:02.523 回答