Утечка памяти при обработке CGMutablePath

У меня возникает утечка памяти при работе с 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;
}

С помощью инструментального анализа я получаю утечку памяти в строке с «return» в textMutablePathForFrame, которая говорит: «Возможная утечка объекта, размещенного в строке 132» (строка 132 — это сама обратная линия).

Я также получаю утечку памяти в textFrameForFrame в строке «CGPathRelease(textMutablePath);», в которой говорится: «Неверное уменьшение счетчика ссылок объекта, который в данный момент не принадлежит вызывающему».

Не могу понять это, я почувствовал, что наконец-то хорошо разобрался с управлением памятью в Core.

ОБНОВЛЕНИЕ: похоже, что это, возможно, ошибка, и я собираюсь проверить ее еще раз, чтобы узнать, чувствует ли кто-то другой.


person Ser Pounce    schedule 29.08.2012    source источник
comment
Вы CFRelease() возвращаете объекты из вызывающей функции?   -  person    schedule 29.08.2012
comment
@ H2CO3 - да, я только что проверил, и во всех случаях, когда я вызываю textMutablePathForFrame, я обычно сохраняю его в локальном CTFrontRef, затем я устанавливаю свойство для этого локального CTFontRef, затем я освобождаю локальный CTFontRef.   -  person Ser Pounce    schedule 29.08.2012
comment
@ H2CO3 - Думаешь, это ошибка?   -  person Ser Pounce    schedule 29.08.2012
comment
@H2CO3 - спасибо за ваш вклад.   -  person Ser Pounce    schedule 29.08.2012
comment
Обратите внимание на комментарий ниже. Анализатор исправен; это не ошибка. Имя должно быть newMutablePathForFrame.   -  person Rob Napier    schedule 29.08.2012
comment
@RobNapier - Спасибо, Роб, это сработало, и я в шоке, никогда бы не понял этого. Вы хотите поставить это как ответ? Кроме того, мне интересно, вы консультируете по iPhone, особенно в области CoreText? У меня есть ваша книга, и я искал вашу контактную информацию, но не смог ее найти.   -  person Ser Pounce    schedule 30.08.2012
comment
Да; мой адрес [email protected].   -  person Rob Napier    schedule 30.08.2012


Ответы (2)


@JonathanCichon в принципе верен, но имеет неправильное соглашение об именах. Правильным соглашением об именах для метода ObjC является newMutablePathForFrame. Анализатор исправен. Правило «Создать» применяется только к Core Foundation. Соглашения об именах ObjC приведены в Расширенное управление памятью. Руководство по программированию. Правила Core Foundation, которые немного отличаются и включают правило «Создать», находятся в файле Руководство по программированию управления памятью для Core Foundation.

person Rob Napier    schedule 30.08.2012

Я не думаю, что у вас есть утечка памяти, измените имя метода textMutablePathForFrame на createMutablePathForFrame, и предупреждения должны исчезнуть.

person Jonathan Cichon    schedule 29.08.2012
comment
Джон, это просто соглашение об именах, изменение имени моего метода ничего не даст. - person Ser Pounce; 29.08.2012
comment
@CoDEFRo Вы CFRelease() возвращаете объекты от вызывающей стороны? - person ; 29.08.2012
comment
анализатор использует соглашения об именах, чтобы печатать предупреждения или нет. Поскольку вы явно создаете и возвращаете новый объект в своем методе, xcode предполагает наличие утечки памяти. Также xcode предполагает, что вы выпускаете объект, которым не владеете, с помощью CGPathRelease(textMutablePath). Чтобы дать xcode подсказку о том, что вы делаете, вы должны следовать соглашениям об именах или просто игнорировать предупреждение. - person Jonathan Cichon; 29.08.2012
comment
похоже, что соглашения об именах работают только с coreFoundation, а не с target-c. Два решения, чтобы избавиться от предупреждений: написать c-функцию и использовать self в качестве второго параметра CGMutablePathRef createMutablePathForFrame(CGRect path, YourClass self) или обернуть путь в UIBezierPath, чтобы он был обработан с помощью ARC/Autorelease. - person Jonathan Cichon; 29.08.2012
comment
@JonathanCichon - Похоже, вы думаете, что это ошибка со стороны Apple? Кстати, спасибо за ваш вклад. - person Ser Pounce; 29.08.2012
comment
Да, я думаю, что Анализатор делает что-то не так. Вы можете написать цикл со многими итерациями и проверять инструменты на наличие утечек, но я уверен, что эти две функции в порядке. - person Jonathan Cichon; 29.08.2012
comment
@JonathanCichon в принципе верен, но имеет неправильное соглашение об именах. Правильным соглашением об именах для метода ObjC является newMutablePathForFrame. Анализатор исправен. Правило Create применяется только к Core Foundation. Соглашения об именах ObjC приведены здесь: developer. apple.com/library/mac/#documentation/Cocoa/Conceptual/. - person Rob Napier; 29.08.2012