Обработка утечек памяти в заводских методах - PullRequest
3 голосов
/ 16 июня 2011

Я занимаюсь разработкой целевой платформы C, которая в конце будет поставляться как статическая библиотека. Но когда я интегрирую эту библиотеку в реальное приложение (добавив статическую библиотеку) в инструменты утечки, я вижу некоторые утечки памяти.

Вот пример сценария.

@implementation Test

@synthesize testNumber

+(Test) createTestInstance {

    Test *test = [[Test alloc] init];
    test.testNumber = [[NSDecimerNumber alloc] initWithInt:1];

    return test;
}

-(void) dealloc {
    [testNumber release];
}

@end

Хотя я выпускаю переменную testNumber в dealloc, я вижу утечку памяти в инструменте Leaks в позиции alloc. В чем может быть проблема здесь?

Кроме того, поскольку это библиотека, предоставляемая пользователю для вызова, рекомендуется ли освобождать эти переменные из кода библиотеки?

Спасибо

1 Ответ

11 голосов
/ 16 июня 2011

Я вижу две проблемы здесь. Если testNumber является сохраняемым свойством, вы переусердствуете с этим утверждением:

test.testNumber = [[NSDecimerNumber alloc] initWithInt:1];

И alloc-init, и средство доступа к свойству сохраняют объект. Поэтому должно быть:

test.testNumber = [[[NSDecimerNumber alloc] initWithInt:1] autorelease];

Нет необходимости упоминать, что вам все еще нужно выпустить testNumber в методе dealloc.

Кроме того, я понимаю, что createTestInstance - это удобный конструктор для создания Test объектов, и он должен возвращать автоматически выпущенный объект в соответствии с Object Ownership Policy (только методы с именами, которые начинаются с «alloc» , «New», «copy» или «mutableCopy» возвращают ваш объект):

+ (id)createTestInstance {

    Test *test = [[[self alloc] init] autorelease];
    test.testNumber = [[[NSDecimerNumber alloc] initWithInt:1] autorelease];

    return test;
}

Наконец, как предлагает @Josh Caswell, вспомогательные конструкторы должны возвращать id вместо определенного класса. С Язык программирования Objective-C :

возвращаемый тип удобства конструкторы является идентификатором по той же причине это идентификатор для методов инициализатора, так как обсуждается в « Ограничениях и соглашениях ».

Кроме того, они должны использовать self вместо жестко закодированного имени класса для выделения-инициализации экземпляра, чтобы правильно обрабатывал подклассы (self здесь относится к самому объекту класса, так как это это метод класса).

...