отключить предупреждение компилятора об освобождении объекта CGMutablePathRef

Я включил статический анализатор, но он сообщает мне, что в конце этого пути выполнения этот объект не освобождается, что, возможно, вызывает утечку памяти. Однако я передаю эту ссылку на созданный объект другому классу, который его выпустит. Мне было интересно, есть ли метод или ключевое слово, чтобы сообщить скомпилированному, что я выпущу этот объект позже.

Я ищу что-то вроде автоматического выпуска.

Кстати, я использую ARC.

Я создаю объект следующим образом:

CGMutablePathRef pathRef = CGPathCreateMutable();

И передать это так:

self.flowView.pathToDraw = pathRef;

В моем классе flowView у меня есть этот метод, который его выпустит.

-(void) setPathToDraw:(CGMutablePathRef) newPath {
    if(pathToDraw!=NULL) CGPathRelease(pathToDraw);
    pathToDraw=newPath;
    [self setNeedsDisplay];
}

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

Спасибо


person Pochi    schedule 22.03.2012    source источник


Ответы (2)


Да, для этого есть расширение:

http://clang.llvm.org/docs/LanguageExtensions.html#objc_features

Вы можете объявить свой метод как:

- (void)setPathToDraw:(CGMutablePathRef) __attribute__((cf_consumed)) newPath

и тогда Clang распознает это (из callsite - он не может проверить, действительно ли вы используете его в определении).

Вы должны убедиться, что каждый селектор, который определяет this, соответствует атрибуту, который вы применили для селектора (имя).

Атрибуты сопряжены с риском — я рекомендую придерживаться соглашений, где это возможно, и быть особенно осторожным при работе с динамической отправкой. Вот пример использования ARC, где компилятор может ошибиться. Если компилятор ошибается, велики шансы, что и вы тоже, потому что вы работаете против инструментов, которые пытаются вам помочь.

IIRC, consume — единственный атрибут, который я использовал, и я использую его исключительно со статической отправкой.

person justin    schedule 22.03.2012

Почему бы вам просто не следовать обычному соглашению о сохранении/выпуске? Я не вижу, что вы надеетесь получить.

Еще один вызов функции сохранения и освобождения не приведет к какой-либо заметной разнице в производительности, и он будет гораздо более понятным для любого, кто когда-либо читал этот код.

CGMutablePathRef pathRef = CGPathCreateMutable();
self.flowView.pathToDraw = pathRef;
CGPathRelease(pathRef);

-(void) setPathToDraw:(CGMutablePathRef) newPath
{
    if (pathToDraw != newPath) {
        CGPathRelease(pathToDraw);
        pathToDraw=CGPathRetain(newPath);

        [self setNeedsDisplay];
    }
}

Если вы настаиваете на странном способе, другой альтернативой является использование атрибута cf_consumed в вашем декларация. Это объясняет анализатору, что вы делаете что-то необычное.

person Kurt Revis    schedule 22.03.2012
comment
Это первое, что я попробовал, но если я отпущу его там, я получаю ошибку доступа к памяти при запуске. - person Pochi; 22.03.2012
comment
Тогда у вас, вероятно, есть еще один дополнительный релиз где-то еще в вашем коде. Надеюсь, вы найдете это! - person Kurt Revis; 23.03.2012