テキスト行の高さを計算するメソッドがあります。ただし、問題は、CTFrameとMalloc(48バイト)の2つの項目でメモリがリークすることです。
その方法の中核は次のとおりです。
(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);
}
行のコメントを外すと、CTFrameは出力されますが、警告が表示されます。
Passing CTFrameRef (aka const struct_CTFrame *) to parameter of type "void *' discards qualifiers)
free(contentFrame);
その場合、リークはMalloc用に1つだけになります。インストルメントツールは、このコード行がリークの原因であることを知らせてくれました。
CTFrameRef contentFrame = CTFramesetterCreateFrame(framesetter, myRange , myPath, nil);
誰でも私がこれを説明するのを手伝うことができます、私はMallocがリークしている理由を説明することはできません。そして、それを修正する方法、CTFrameオブジェクトを解放する方法も?
私はたくさん研究しましたが、解決策を見つけることができませんでした。