处理 CGMutablePath 时的内存泄漏

Posted

技术标签:

【中文标题】处理 CGMutablePath 时的内存泄漏【英文标题】:Memory Leak When Handling CGMutablePath 【发布时间】:2012-08-29 07:28:40 【问题描述】:

在以下情况下使用CGMutablePath 时出现内存泄漏:

- (CGMutablePathRef) textMutablePathForFrame:(CGRect)frame

    CGAffineTransform transform = CGAffineTransformMakeScale(frame.size.width / self.shapeMutablePathSize.width, frame.size.height / self.shapeMutablePathSize.height);

    return CGPathCreateMutableCopyByTransformingPath(self.shapeMutablePath, &transform);


- (CTFrameRef) textFrameForFrame:(CGRect)frame framesetter:(CTFramesetterRef)framesetter

    CGMutablePathRef textMutablePath = [self textMutablePathForFrame:frame];
    CTFrameRef textFrame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), textMutablePath, NULL);
    CGPathRelease(textMutablePath);

    return textFrame;

通过仪器分析,我在textMutablePathForFrame 中带有“return”的行出现内存泄漏,上面写着“在第 132 行分配的对象的潜在泄漏”(第 132 行是返回行本身)。

我还在textFrameForFrame 中的“CGPathRelease(textMutablePath);”行中发现内存泄漏:“调用者此时不拥有的对象的引用计数递减不正确”。

对此我无法理解,感觉我终于对 Core 中的内存管理有了一个很好的理解。

更新:看起来这可能是一个错误,将再次碰撞它,看看其他人是否有不同的感觉。

【问题讨论】:

CFRelease()调用函数返回的对象吗? @H2CO3 - 是的,我刚刚检查过,在所有情况下,当我调用 textMutablePathForFrame 时,我通常将它存储在本地 CTFrontRef 中,然后我为该本地 CTFontRef 设置一个属性,然后我释放本地CTFontRef. @H2CO3 - 认为这可能是一个错误? @H2CO3 - 感谢您的意见。 注意下面的评论。分析仪是正确的;这不是错误。名称应为newMutablePathForFrame 【参考方案1】:

@JonathanCichon 原则上是正确的,但命名约定错误。 ObjC 方法的正确命名约定是newMutablePathForFrame。分析仪是正确的。 “创建”规则仅适用于 Core Foundation。 ObjC 命名约定在Advanced Memory Management Programming Guide 中。核心基础规则略有不同,包括“创建”规则,位于Memory Management Programming Guide for Core Foundation。

【讨论】:

【参考方案2】:

我认为您没有内存泄漏,请将您的 textMutablePathForFrame 方法名称更改为 createMutablePathForFrame,警告应该会消失。

【讨论】:

Jon 这只是一个命名约定,更改我的方法的名称不会完成任何事情。 @CoDEFRo 你 CFRelease() 调用者返回的对象吗? 分析器使用命名约定来打印或不打印警告。当您清楚地在方法中创建并返回一个新对象时,xcode 假定存在内存泄漏。 xcode 还假设您正在使用CGPathRelease(textMutablePath) 释放您不拥有的对象。要给 xcode 提示您正在做什么,您必须遵循命名约定,或者忽略警告。 看起来命名约定只适用于 coreFoundation 而不是 Objective-c。消除警告的两种解决方案:编写一个 c 函数并将 self 作为第二个参数 CGMutablePathRef createMutablePathForFrame(CGRect path, YourClass self) 或将路径包装在 UIBezierPath 中,以便在 ARC/Autorelease 进行处理。 @JonathanCichon - 所以听起来你认为这是 Apple 的错误?顺便说一句,感谢您的意见。

以上是关于处理 CGMutablePath 时的内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

使用 SharedResourceDictionary 时的内存泄漏

使用 AFHTTPSessionManager 时的内存泄漏

BaseHandler的封装, 处理handler中的内存泄漏

使用 setText 时的内存泄漏

使用 MPMoviePlayerController 时的内存泄漏

使用 destroy() 命令时的 Perl/Tk 内存泄漏