Как предотвратить определенные виды отчетов об утечках из анализатора? - PullRequest
2 голосов
/ 11 марта 2011

Я обертываю определенный C API в Objective-C. У меня есть удобный метод, который берет некоторые CFTypeRef из процедурного API и возвращает объект обтекания из OOP API. Этот объект сохраняет переданный CFTypeRef и освобождает его по своему собственному освобождению. Удобный метод выглядит так:

+ (id) wrapFoo: (CFTypeRef) foo;

У меня есть много методов, которые просто получают CFTypeRef и возвращают объект обтекания:

- (id) doSomething {
    CFTypeRef foo = CFCreateSomeObject();
    id wrapper = [WrappingClass wrapFoo:foo];
    CFRelease(foo);
    return wrapper;
}

Это немного неуклюже, так что я предложил другой удобный метод:

+ (id) wrapNonRetainedFoo: (CFTypeRef) foo {
    id wrapper = [self wrapFoo:foo]; // CFRetains foo
    CFRelease(foo);
    return wrapper;
}

Теперь я могу переписать метод doSomething следующим образом:

- (id) doSomething {
    return [WrappingClass wrapNonRetainedFoo:CFCreateSomeObject()]; // XXX
}

Мне это нравится. Я не очень горжусь методом wrapNonRetainedFoo, но он не является частью общедоступного интерфейса пакета и экономит мне несколько строк стандартного кода в нескольких методах.

Недостатком является то, что статический анализатор помечает линию XXX как потенциальную утечку. Что я могу сделать лучше? Я попытался поиграть с атрибутом аргумента cf_consumed, чтобы дать анализатору понять, что я освобождаю объект позже, но, похоже, он не работает.

1 Ответ

2 голосов
/ 11 марта 2011

1) AFAIK cf_consumed по-прежнему не поддерживается в версиях анализатора, который использует Apple.

2) Я заметил, что если вы сделаете wrapNonRetainedFoo, предупреждение о методе экземпляра таинственно исчезнет.Но так как wrap... лучше использовать в качестве метода класса, это бесполезно для нас.

3) Единственное решение, о котором я могу подумать, - это некрасивый макрос (не для производства, просто как доказательство концепции):

#define WRAP_CFTYPE(klass, valExpr) ({ CFTypeRef val = valExpr; id result = [klass wrap:val]; CFRelease(val); result; })

Использование:

WrappingClass *wrapper = WRAP_CFTYPE(WrappingClass, CFArrayCreate(NULL, NULL, 0, NULL))
...