Управление памятью iOS запуталось - PullRequest
0 голосов
/ 11 января 2012

У меня есть статический метод в классе Utilities:

+ (Division *) getDefaultDivision
{
    Division *defaultDivision = [[Division alloc] init];
    defaultDivision.Id = 0;
    defaultDivision.name = @"Accounting";
    defaultDivision.slug = @"accounting";

    return defaultDivision;
}

И в моем ViewController я делаю что-то вроде:

Division *div = [[Division alloc] init];
div = [Utilities getDefaultDivision];

Но когда я анализирую, он говорит "Потенциальная утечка"объекта, размещенного в строке x и сохраненного в defaultDivision ".

Если я использую:

Division *defaultDivision = [[[Division alloc] init] autorelease];

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

Просто интересно, что здесь правильно делать?

Ответы [ 2 ]

3 голосов
/ 11 января 2012

Если это ваш реальный код;

Division *div = [[Division alloc] init];
div = [Utilities getDefaultDivision];

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

1 голос
/ 11 января 2012

Независимо от того, как реализован «getDefaultDivision», у вас есть утечка в этом коде:

Division *div = [[Division alloc] init];
div = [Utilities getDefaultDivision];

Строка 1 выделяет память и назначает div для указания на эту память. Вы должны освободить эту память в какой-то момент. Но после строки 2 это становится невозможным, поскольку div теперь имеет новое значение - и указатель на память, выделенную в строке 1, равен потерян . Это утечка. Пока не поймешь почему, ты на тонком льду.

Что касается этого метода:

+ (Division *) getDefaultDivision
{
    Division *defaultDivision = [[Division alloc] init];
    defaultDivision.Id = 0;
    defaultDivision.name = @"Accounting";
    defaultDivision.slug = @"accounting";
    return defaultDivision;
}

Это иногда называют «фабричным» методом - статическим служебным методом для выделения, инициализации и возврата ссылки на новый экземпляр класса. Лучшей практикой здесь является использование автоматического выпуска в заводских методах. E.g.:

Division *defaultDivision = [[[Division alloc] init] autorelease];

Почему это лучшая практика? Согласно руководству Apple по управлению памятью, только методы со следующими терминами должны возвращать ссылки на объекты, которые вызывающий отвечает за освобождение:

alloc, allocWithZone:, copy, copyWithZone:, mutableCopy, mutableCopyWithZone:

- от http://developer.apple.com/library/IOs/#documentation/General/Conceptual/DevPedia-CocoaCore/MemoryManagement.html

Поскольку «getDefaultDivision» не является методом «alloc» или «copy» (это метод доступа), он не должен возвращать указатель на объект, который вызывающая сторона должна впоследствии освободить, чтобы избежать утечки. Пометка вновь выделенной возвращенной памяти в качестве автоматического выпуска является одним из способов соблюдения этого контракта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...