处理 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中的内存泄漏