Использование инструментов Утечки и Распределение объектов: Считаются ли автоматически выпущенные объекты как утечки? - PullRequest
6 голосов
/ 23 марта 2009

У меня есть приложение для iPhone, которое получает предупреждения о памяти, и поэтому я пытаюсь найти утечки, более эффективно использовать память и т. Д. С помощью инструментов. Помимо прочего, я пытаюсь удалить любые автоматически освобожденные объекты и заменить их на объекты alloc / init / release вручную. Однако некоторые вызовы API, по-видимому, не имеют версии init (см. Код ниже). По общему признанию, у меня есть несколько основных недоразумений:

  1. Если я 'вызову' API и получу обратно по существу автоматически выпущенные объекты, могут ли эти объекты отображаться как утечки в Инструментах? Кажется, я вижу это поведение в инструментах.

  2. Если да к 2, должен ли я просто проигнорировать, если нет альтернативы «без авто-релиза», и я использую API, который мне нужен? Кроме того, если этот код часто вызывается, я должен полностью переосмыслить алгоритм?

Вот некоторый служебный код из моего приложения, который часто вызывается. В основном определяет, являются ли две даты значимо «равными». Я оставил в закомментированном коде, чтобы вы могли видеть типы улучшений, которые мне нужны, в моей кодовой базе - этот DID уменьшает утечки памяти при последующем запуске в Instruments , когда я начал создавать вручную NSDate (и выпуск), который помог. Тем не менее, у меня все еще есть объекты компонента date, которые, как мне кажется, протекают ... но это вызов API (извините за форматирование кода, но я не могу улучшить его в SO):

+ (BOOL)isDayEqualToDay:(NSDate*)date anotherDate:(NSDate*)anotherDate
{

    NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];  
    //NSCalendar *cal;  
    NSDateComponents *componentsFromDate, *componentsFromAnotherDate;   
    NSUInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;    
    //cal = [NSCalendar currentCalendar];
    componentsFromDate = [cal components:unitFlags fromDate:date];
    componentsFromAnotherDate = [cal components:unitFlags fromDate:anotherDate];

    BOOL bDatesEqual = ([componentsFromDate year] == [componentsFromAnotherDate year] && 
                        [componentsFromDate month] == [componentsFromAnotherDate month] && 
                        [componentsFromDate day] == [componentsFromAnotherDate day]);

    [cal release];

    return bDatesEqual;

    /*
    return (
        [componentsFromDate year] == [componentsFromAnotherDate year] &&
        [componentsFromDate month] == [componentsFromAnotherDate month] && 
        [componentsFromDate day] == [componentsFromAnotherDate day]
    );*/
}

Я думаю, что componentFromDate и componentsFromAnotherDate отображаются как утечки, но там только объекты, по существу возвращаемые из вызова API NSData (autoreleased). Не уверен, что еще я мог бы сделать, чтобы сделать это более эффективным, и я подвергаю сомнению мое понимание того, как лучше всего использовать Инструменты. Предложения?

Ответы [ 2 ]

4 голосов
/ 25 марта 2009

Автоматически освобожденный объект не должен отображаться как утечка памяти. Однако иногда API имеют утечки памяти. Вы должны подать отчет об ошибке с яблоком. Новые классы, такие как NSCalendar и NSDateComponenets, особенно подозрительны.

Что касается сохранения против автоматического выпуска, то общее правило состоит в том, что это не имеет значения, если вы не находитесь в тесной петле. В этом случае, если замкнутый цикл выполняется много тысяч раз без события, это означает, что вы никогда не «очистите» пул авто-выпуска.

3 голосов
/ 05 апреля 2011

При использовании таких вещей, как GCD, существует пул авто-релиза, но вы не можете знать, когда (если вообще когда-либо) пул авто-релиза по умолчанию истощается. Если вы уверены, что atoreleased объекты не освобождают, убедитесь, что вы понимаете API потоков, который вы используете. Если память мне не изменяет, GCD-вызовы (dispatch_async) разбирают пулы автоматического выпуска для вас, НО фактическое удаление пула может занять много времени. Операции NSO, с другой стороны, позволяют вам создавать пулы автоматического выпуска.

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

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
... [your code] ...
[pool drain];

Я бы рекомендовал не пытаться заменить все авто-релизы на ручные релизы. Использование автоматического выпуска приводит к сбалансированному счету удержания / разблокировки вызовов в одном месте. Создание объекта с последующим его автоматическим выпуском, по моему мнению, предотвращает множество ошибок памяти. Быстро, легко. Вы забудете отпустить материал, когда будете делать вызовы вручную. Особенно сложные ошибки при выполнении ручных выпусков.

Создание пула самостоятельно дает вам больший контроль, а во время интенсивной работы с распределением иногда полезно создавать и использовать свои собственные пулы. Но, как всегда, попробуй и проверь, не делай никаких предположений.

...