UIView drawRect 与 CoreText 泄漏

发布于 2024-11-30 06:18:27 字数 2333 浏览 1 评论 0原文

我有一个无法追踪的泄漏。我是 CoreText(以及一般的 C)新手,所以请保持温柔!静态分析器没有显示任何问题,但 Instruments 在这种方法中出现了问题:

- (void)drawAttributedStringInBubbleInContext:(CGContextRef)context {
    static CGFloat const kTextInset = 10;

    // Add the text to the bubble using an ellipse path inside the main speech bubble if the text property is set
    if (text) {

        // Create an attributed string from the text property
        NSMutableAttributedString *bubbleText = [[NSMutableAttributedString alloc] initWithString:text];        

        // Justify the text by adding a paragraph style
        CFIndex stringLength = CFAttributedStringGetLength((CFAttributedStringRef)bubbleText);
        CTTextAlignment alignment = kCTJustifiedTextAlignment;
        CTParagraphStyleSetting _settings[] = {
            {kCTParagraphStyleSpecifierAlignment, sizeof(alignment), &alignment}
        };      
        CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(_settings, sizeof(_settings) / sizeof(_settings[0]));
        CFRange stringRange = CFRangeMake(0, stringLength);
        CFAttributedStringSetAttribute((CFMutableAttributedStringRef)bubbleText, stringRange, kCTParagraphStyleAttributeName, paragraphStyle);
        CFRelease(paragraphStyle);      

        // Layout the text within an elliptical frame
        CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)bubbleText);

        // Create elliptical path that is inset from the frame of the view
        CGMutablePathRef path = CGPathCreateMutable();
        CGRect drawingRect = self.bounds;
        drawingRect.origin.x = kTextInset;
        drawingRect.origin.y = kTextInset;
        drawingRect.size.width -= 2 * kTextInset;
        drawingRect.size.height -= 2 * kTextInset;
        CGPathAddEllipseInRect(path, NULL, drawingRect);

        // Create a text frame from the framesetter and the path 
        CTFrameRef textFrame = CTFramesetterCreateFrame(framesetter,CFRangeMake(0,0), path, NULL);

        // Draw the text frame in the view's graphics context
        CTFrameDraw(textFrame, context);

        // Clean up
        CGPathRelease(path);
        CFRelease(framesetter);
        [bubbleText release];
    }
}

根据 Instruments 的说法,罪魁祸首是 CTFrameRef textFrame = 行,尽管我认为我已经正确释放了所有内容。

I have a leak that I can't track down. I am new to CoreText (and C in general) so please be gentle! The static analyser doesn't show any problems but Instruments does in this method:

- (void)drawAttributedStringInBubbleInContext:(CGContextRef)context {
    static CGFloat const kTextInset = 10;

    // Add the text to the bubble using an ellipse path inside the main speech bubble if the text property is set
    if (text) {

        // Create an attributed string from the text property
        NSMutableAttributedString *bubbleText = [[NSMutableAttributedString alloc] initWithString:text];        

        // Justify the text by adding a paragraph style
        CFIndex stringLength = CFAttributedStringGetLength((CFAttributedStringRef)bubbleText);
        CTTextAlignment alignment = kCTJustifiedTextAlignment;
        CTParagraphStyleSetting _settings[] = {
            {kCTParagraphStyleSpecifierAlignment, sizeof(alignment), &alignment}
        };      
        CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(_settings, sizeof(_settings) / sizeof(_settings[0]));
        CFRange stringRange = CFRangeMake(0, stringLength);
        CFAttributedStringSetAttribute((CFMutableAttributedStringRef)bubbleText, stringRange, kCTParagraphStyleAttributeName, paragraphStyle);
        CFRelease(paragraphStyle);      

        // Layout the text within an elliptical frame
        CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)bubbleText);

        // Create elliptical path that is inset from the frame of the view
        CGMutablePathRef path = CGPathCreateMutable();
        CGRect drawingRect = self.bounds;
        drawingRect.origin.x = kTextInset;
        drawingRect.origin.y = kTextInset;
        drawingRect.size.width -= 2 * kTextInset;
        drawingRect.size.height -= 2 * kTextInset;
        CGPathAddEllipseInRect(path, NULL, drawingRect);

        // Create a text frame from the framesetter and the path 
        CTFrameRef textFrame = CTFramesetterCreateFrame(framesetter,CFRangeMake(0,0), path, NULL);

        // Draw the text frame in the view's graphics context
        CTFrameDraw(textFrame, context);

        // Clean up
        CGPathRelease(path);
        CFRelease(framesetter);
        [bubbleText release];
    }
}

The main culprit according to Instruments is the CTFrameRef textFrame = line, although I thought I have released everything properly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

↘紸啶 2024-12-07 06:18:28

这就是罪魁祸首,核心基础规则Create 方法是你必须释放它们的。 Apple 在 Core 中的示例中正确发布了它文本编程指南

    // Clean up
    CGPathRelease(path);
    CFRelease(framesetter);
    CFRelease(textFrame);

That is the culprit, the Core Foundation rule for Create methods are you have to release them. Apple releases it properly in an example in the Core Text Programming Guide.

    // Clean up
    CGPathRelease(path);
    CFRelease(framesetter);
    CFRelease(textFrame);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文