Утечка памяти CoreText из CFramesetterCreateWithAttributedString

Я столкнулся с проблемной утечкой, которая, благодаря Instruments, кажется, исходит от CTFrameSetterCreateWithAttributedString. Стек вызовов ниже.

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

Код, генерирующий этот стек вызовов:

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

self.attributedString выпускается в другом месте. Я чувствую, что правильно публикую все остальное... Учитывая все это, откуда может быть утечка? Для моих целей это довольно существенно - 6-10 МБ на поп. Спасибо за любую помощь.


person beaudrykock    schedule 23.04.2012    source источник
comment
До сих пор не могу понять это и подозреваю, что это может быть ошибка Apple. Подали отчет - обновлю здесь, если будет ответ.   -  person beaudrykock    schedule 30.04.2012
comment
Вы сказали self.attributedString gets released elsewhere, а отпускаете attrRef во фрагменте кода выше. Возможно, именно ваш выпуск этого объекта дважды вызывает некоторые другие проблемы, которые влияют на другой код, а CFRelease вообще не вызывается, просто предположение...   -  person neevek    schedule 11.05.2012
comment
Интересная идея - спасибо. Но я думаю, что CFRelease() просто выпускает объекты Core Foundation, а любые объекты Cocoa (например, NSAttributedString) должны выпускаться отдельно.   -  person beaudrykock    schedule 11.05.2012
comment
Если вы находитесь в рамках ARC, вам редко приходится иметь дело с освобождением объектов Cocoa (если только вы не передаете право собственности на объекты Cocoa объектам Core Foundation), (CFAttributedStringRef)self.attributedString похоже на (__bridge CFAttributedStringRef)self.attributedString, который не передает право собственности на self.attributedString другому CFAttributedStringRef, так что вам не следовало звонить CFRelease на attrRef . Если вы хотите управлять освобождением памяти объекта на стороне Core Foundation, вам нужны __bridge__transfer или CFRetain, но я не думаю, что вы должны это делать.   -  person neevek    schedule 11.05.2012
comment
Я не под ARC, но я понимаю вашу точку зрения. В любом случае, я попытался удалить дополнительный CFRelease на attRef, но это не решает проблему (к сожалению!)   -  person beaudrykock    schedule 11.05.2012
comment
stackoverflow.com /вопросы/8491841/   -  person MoDJ    schedule 22.06.2013


Ответы (1)


Оказывается, эта проблема была существенно решена за счет отказа от использования ivar для CFMutableArrayRef. Мы использовали оболочку Akosma Obj-C для CoreText, а в классе AKOMultiColumnTextView есть переменная CFMutableArrayRef _frames ivar, которая по какой-то причине зависает даже после вызовов CFRelease. Отсутствие переменной _frames немного дороговато, но значительно улучшило использование памяти. Спасибо, Нивек, за ваш вклад.

person beaudrykock    schedule 22.05.2012