I draw a table "by hand", by using primitives of Core Graphics. The view is re-draw when I click a button. The problem is that when I profile the code in Instruments, the VM Regions keep increase, while Heap and Anonymous VM oscillate (and I would expect it).
And the details about CoreAnimation:
An excerpt of my drawRect:
- (void)drawRect:(CGRect)rect
{
// Drawing code
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect paperRect = CGRectMake(self.bounds.origin.x+hourLabelSize+self.marginX,
10 +self.cellBorder ,
self.bounds.size.width,
self.cellHeight * 48
);
// custom shadow
drawLinearGradient(context, paperRect, whiteColor.CGColor, lightGrayColor.CGColor);
CGContextSaveGState(context);
CGFloat outerMargin = 5.0f;
CGFloat eventSize;
// Draw table
CGRect hourRect;
CGRect outerRect;
CGMutablePathRef outerPath;
CGRect strokeRect;
CGRect rowRect;
for (int j=0; j < 7;j++)
{
for (int i=0; i < numberOfRows; i++)
{
// Odd index means we are in the half of an hour
if ( (i%2) == 0)
{
[hour setString:[NSString stringWithFormat:@"%d:00",(int)floor(i/2)]];
// Draw box around hours //
if (j == 0 && i >0)
{
CGContextSaveGState(context);
hourRect = CGRectMake(5, i*cellHeight-5, hourLabelSize, 28);
outerRect = CGRectInset(hourRect, outerMargin, outerMargin);
outerPath = newRoundedRectForRect(outerRect, 6.0);
CGContextAddPath(context, outerPath);
CFRelease(outerPath); // <--- This solve the leak!!
// Draw gradient
strokeRect = CGRectInset(hourRect, 5.0, 5.0);
CGContextSetStrokeColorWithColor(context, boxColor.CGColor);
CGContextSetLineWidth(context, 1.0);
CGContextStrokeRect(context, strokeRect);
drawLinearGradient(context, strokeRect, whiteColor.CGColor, lightGrayColor.CGColor);
CGContextRestoreGState(context);
}
}
else
{
[hour setString:[NSString stringWithFormat:@"%d:30",(int)floor(i/2)]];
}
// Draw hours
if (j == 0 && i > 0)
[hour drawInRect:CGRectMake(0, i*cellHeight, hourLabelSize+10, 26) withFont:font lineBreakMode:NSLineBreakByClipping alignment:NSTextAlignmentCenter];
// Draw row
CGContextBeginPath(context);
CGContextSetStrokeColorWithColor(context, boxColor.CGColor);
CGContextSetLineWidth(context, self.cellBorder);
rowRect = CGRectMake(j*cellWidth + hourLabelSize +self. marginX - self.cellBorder/2, i*cellHeight+10 + self.cellBorder / 2, cellWidth , cellHeight);
CGContextStrokeRect(context, rowRect);
} //
CGContextFlush(context);
CGContextRestoreGState(context);
The first thing I do not understand is why I see VM:CoreAnimation. CoreGraphics is part of Core Animation? Secondly, what I shall watch as syntoms of bad allocation: VM Regions, XCode measurements or Head and Anonymous? Regards!
[EDIT]
The createRoundedRect
is as follows
CGMutablePathRef newRoundedRectForRect(CGRect rect, CGFloat radius)
{
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, CGRectGetMidX(rect), CGRectGetMinY(rect));
CGPathAddArcToPoint(path, NULL, CGRectGetMaxX(rect), CGRectGetMinY(rect), CGRectGetMaxX(rect), CGRectGetMaxY(rect), radius);
CGPathAddArcToPoint(path, NULL, CGRectGetMaxX(rect), CGRectGetMaxY(rect), CGRectGetMinX(rect), CGRectGetMaxY(rect), radius);
CGPathAddArcToPoint(path, NULL, CGRectGetMinX(rect), CGRectGetMaxY(rect), CGRectGetMinX(rect), CGRectGetMinY(rect), radius);
CGPathAddArcToPoint(path, NULL, CGRectGetMinX(rect), CGRectGetMinY(rect), CGRectGetMaxX(rect), CGRectGetMinY(rect), radius);
CGPathCloseSubpath(path);
return path;
}:
and the drawLineGradient.m
:
void drawLinearGradient(CGContextRef context, CGRect rect, CGColorRef startColor, CGColorRef endColor)
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[] = { 0.0, 1.0 };
NSArray *colors = @[(__bridge id) startColor, (__bridge id) endColor];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef) colors, locations);
CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextSaveGState(context);
CGContextAddRect(context, rect);
CGContextClip(context);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGContextRestoreGState(context);
CGGradientRelease(gradient);
CGColorSpaceRelease(colorSpace);
colors = nil;
}
The reason you see core animation is because all iOS views are layer-backed views. The reason for your leak is that you release the path. ARC does not manage Core Foundation objects.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With