Tell me more ×
Ask Different is a question and answer site for power users of Apple hardware and software. It's 100% free, no registration required.

I have a method that will calculate the height of a text line. But the problem is it leak the memory with 2 items: CTFrame and a Malloc (48 byte).

Here are the core of that method:

  • (void)calculatePageHeight {
__weak UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.view.bounds];

NSString *sampleText = @"The CTFont opaque type represents a Core Text font object. Font objects represent fonts to an application, providing access to characteristics of the font, such as point size, transform matrix, and other attributes. Fonts provide assistance in laying out glyphs relative to one another and are used to establish the current font when drawing in a graphics context.";
NSRange contentRange = NSRangeFromString(sampleText);
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:sampleText attributes:self.textAttributes];

CFAttributedStringRef attributeRef = (__bridge CFAttributedStringRef)attributedString;

CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attributeRef);

CGPathRef myPath = [path CGPath];
CFRange myRange = CFRangeMake(contentRange.location, contentRange.length);

CTFrameRef contentFrame = CTFramesetterCreateFrame(framesetter, myRange , myPath, nil);
CFArrayRef lines = CTFrameGetLines(CFRetain(contentFrame));
NSInteger lineCount = CFArrayGetCount(lines);
CGPoint *origins = calloc(lineCount, sizeof(CGPoint));

CTFrameGetLineOrigins(contentFrame, CFRangeMake(0, 0), origins);
CGFloat lineSpacing = 0;

for (NSInteger index = 0; index < lineCount; index ++) {
    CTLineRef line = CFArrayGetValueAtIndex(lines, index);
    CGFloat ascent;
    CGFloat descent;

    CTLineGetTypographicBounds(line, &ascent, &descent, nil);
    NSLog(@"line height: %f", ascent + (descent * 2));

    lineSpacing = ascent + (descent * 2);
}
free(origins);
CFRelease(lines);
//free(contentFrame);

NSLog(@"line spacing: %f", lineSpacing);

NSInteger numberOfLine = TEXT_PAGE_HEIGHT / (lineSpacing);

CGFloat pageHeight = numberOfLine * (lineSpacing);
self.pageHeight = pageHeight;

CGPathRelease(myPath);
CFRelease(framesetter);

} <

When I uncomment the line, the CTFrame will be out, but there will be a waringing (Passing CTFrameRef (aka const struct_CTFrame *) to parameter of type "void *' discards qualifiers).

> free(contentFrame); <

then the leaking will have only one for Malloc.

The instrument tool let me know this line of code cause the leaking. > CTFrameRef contentFrame = CTFramesetterCreateFrame(framesetter, myRange , myPath, nil); <

Any one can help me to explain this, I can not explain why the Malloc is leaking. And how to fix that, how to release CTFrame object as well ?

I research so much but could not found a solution.

share|improve this question
This should be moved to Stackoverflow.. – mspasov May 6 '12 at 12:12
Questions about programming, development, and listing your apps on the App Store are off topic for Ask Different. – Daniel Lawson May 6 '12 at 12:18

closed as off topic by Daniel Lawson May 6 '12 at 12:19

Questions on Ask Different are expected to relate to Apple hardware or software within the scope defined in the FAQ. Consider editing the question or leaving comments for improvement if you believe the question can be reworded to fit within the scope. Read more about closed questions here.

Browse other questions tagged or ask your own question.