1

I'm coming across a problematic leak which - thanks to Instruments - appears to be coming from CTFrameSetterCreateWithAttributedString. The call stack is below.

1 CoreText -[_CTNativeGlyphStorage prepareWithCapacity:preallocated:]
2 CoreText -[_CTNativeGlyphStorage initWithCount:]
3 CoreText +[_CTNativeGlyphStorage newWithCount:]
4 CoreText TTypesetterAttrString::Initialize(__CFAttributedString const*)
5 CoreText TTypesetterAttrString::TTypesetterAttrString(__CFAttributedString const*)
6 CoreText TFramesetterAttrString::TFramesetterAttrString(__CFAttributedString const*)
7 CoreText CTFramesetterCreateWithAttributedString

The code generating this call stack is:

CFAttributedStringRef attrRef = (CFAttributedStringRef)self.attributedString;
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrRef);
CFRelease(attrRef);
...
CFRelease(framesetter);

self.attributedString gets released elsewhere. I feel like I'm correctly releasing everything else... Given all this, where could the leak be coming from? It's fairly significant for my purposes - 6-10 MB a pop. Thanks for any help.

beaudrykock
  • 248
  • 2
  • 17
  • Still can't figure this one out, and suspect it might be an Apple bug. Have filed a report - will update here if any response. – beaudrykock Apr 30 '12 at 16:36
  • You said `self.attributedString gets released elsewhere`, while you release `attrRef` in the code snippet above. Maybe it is your releasing that object twice that causes some other problems, which affects other code, and CFRelease is not called at all, just guessing... – neevek May 11 '12 at 04:08
  • Interesting idea - thanks. But I think that ```CFRelease()``` just releases Core Foundation objects, and any Cocoa objects (like NSAttributedString) must be released separately. – beaudrykock May 11 '12 at 08:59
  • If you are under ARC, you rarely need to deal with deallocation of Cocoa objects(unless you transfer ownership of Cocoa objects to Core Foundation objects), `(CFAttributedStringRef)self.attributedString` is like `(__bridge CFAttributedStringRef)self.attributedString`, which **does not** transfer ownership of `self.attributedString` to `CFAttributedStringRef`, so you shouldn't have called `CFRelease` on `attrRef `. If you want to manage memory deallocation of the object in the Core Foundation side, `__bridge__transfer` or `CFRetain` is what you need, but I don't think you should. – neevek May 11 '12 at 09:18
  • I'm not under ARC, but I see your point. In any case, I tried removing the additional ```CFRelease``` on ```attRef``` but it doesn't deal with the problem (unfortunately!) – beaudrykock May 11 '12 at 12:47
  • http://stackoverflow.com/questions/8491841/memory-usage-grows-with-ctfontcreatewithname-and-ctframesetterref/17248890#17248890 – MoDJ Jun 22 '13 at 08:51

1 Answers1

0

Turns out this problem was substantially addressed by not using an ivar for a CFMutableArrayRef. We were using the Akosma Obj-C wrapper for CoreText, and in the AKOMultiColumnTextView class there's a CFMutableArrayRef _frames ivar which - for some reason - is hanging around even after CFRelease calls. Not having the _frames ivar is a bit expensive, but has drastically improved memory usage. Thanks Neevek for your contributions.

beaudrykock
  • 248
  • 2
  • 17