我需要帮助。
我有自定义的 uitableviewcell,里面有 uiscrollview,我遍历一个 nsarray 并使用 addsubview: 方法将自定义 uiviews(只是子类化 drawrect: 并进行自定义绘图)添加到我的滚动视图中,我每秒刷新一次,它给我一个内存警告并让我崩溃应用程序。我的项目是ARC,我不能调用release。我认为这不是最好的解决方案。
谢谢。
简单的。不要显示 5000 个视图,或者只创建/保留您必须呈现的视图。
清除不可见的内容 - 或者 - 如果它们都同时可见,请使用不同的方法进行渲染。
贾斯汀的答案的改进,如果有一个数据列表,那么你最好看看 UITableView 是如何工作的。
如果您正在考虑构建一个游戏并同时在屏幕上显示许多小图形,那么您最好使用 Cocos2d 或 Sparrow 等主要的 2d 渲染库。
这些是您可以实现贾斯汀想法的几种方法,前者仅在使用每一行时绘制(换句话说,保留在内存中)。后者是为处理大量较小的图像而构建的,并且通过执行自定义绘制例程在处理大量图形时表现更好。
最后,我使用我的第二种方法(自定义绘制单个 UIView 并将其添加到我的滚动视图)感谢大家的帮助。
如果它只是在几次刷新后崩溃,那意味着你可能有内存泄漏。
很有可能你正在使用一些 CG 的东西。Core Graphics 的东西不是由 ARC 维护的,你需要做 CG 发布。您可以通过添加任何缺少的版本来解决此问题,或者如果您不在后台线程中执行图形处理,则通常可以使用 UI 等效项。
是的,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];
}