我有一种方法可以计算文本行的高度。但问题是它使用 2 项泄漏内存:CTFrame 和 Malloc(48 字节)。
以下是该方法的核心:
(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。仪器工具让我知道这行代码导致泄漏。
CTFrameRef contentFrame = CTFramesetterCreateFrame(framesetter, myRange , myPath, nil);
任何人都可以帮助我解释这一点,我无法解释为什么 Malloc 会泄漏。以及如何解决这个问题,如何释放 CTFrame 对象?
我研究了很多,但找不到解决方案。