Инструменты говорят, что я пропускаю строку, но я не могу найти ее - PullRequest
0 голосов
/ 23 сентября 2011

Я использовал инструмент утечки в Инструментах для проверки кода, но инструмент утечки не может найти утечку.

В конце моего кода вывод NSLog(@"str count:%d",[str retainCount]); равен 3. Почему? Я не отменяю сделку. [a.name retainCount] есть только один раз и я только autorelease str на один раз. Так что ул не должен течь.

@interface DataMode : NSObject {

    NSString * name;
}

@property (retain) NSString * name;

- initWithName:(NSString * )name_;
@end


@implementation DataMode

@synthesize name;

- initWithName:(NSString * )name_
{
    if ([super init] != nil)
    {
        name = name_;
        return self;
    }
    return nil;
}

@end


- (void) pressed:(id)sender
{
    for( int i = 0;i<10000000;i++)
    {
        NSString * str = [NSString stringWithFormat:@"zhang"];
        DataMode * a = [[DataMode alloc] initWithName:str];
        NSLog(@"a0 count:%d",[a retainCount]);
        NSLog(@"name1 count:%d",[a.name retainCount]);
        NSLog(@"name1 count:%d",[a.name retainCount]);
        NSLog(@"a1 count:%d",[a retainCount]);
        [ a  release];
        NSLog(@"str count:%d",[str retainCount]);
        NSLog(@"str count:%d",[str retainCount]);
    }


}
@end

Ответы [ 3 ]

3 голосов
/ 23 сентября 2011

retainCount бесполезен. Не называй это.

Это бесполезно для обнаружения утечек, поскольку есть намного лучшие, более точные и менее вводящие в заблуждение инструменты.

Есть несколько проблем с вашим кодом (но утечка не является одной из них):

  • NSString * свойства должны быть copy

  • вы не используете свойство для установки строкового значения в init, поэтому экземпляры DataMode не сохраняют свои строки.

  • не существует метода dealloc

Что касается удержания; Я удивлен, что это «3». Я ожидал бы, что это будет 2bazillionsomething, поскольку это константная строка (а stringWithString: из константной строки просто возвращает строку). Поскольку вы использовали stringWithFormat:, константная строка превращается в непостоянную строку , Если бы вы использовали постоянную строку или stringWithString:, это было бы что-то недопустимое (без знака -1 ... UINT_MAX ...).

В любом случае у вас есть:

  • + 1 для stringWithString:
  • + 1 для звонка a.name
  • + 1 для звонка a.name

+ 3 в целом.

Если Instruments заявляет об утечке, опубликуйте скриншот.

0 голосов
/ 23 сентября 2011

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

Проверьте мой ответ на другой вопрос и добавьте эти методы к DataMode и вы должны увидеть, когда фреймворк освободит ваши объекты из пула автоматического выпуска.

Переопределение освобождения и сохранение в вашем классе

0 голосов
/ 23 сентября 2011

Я цитирую ссылка на протокол NSObject для -retainCount:

Этот метод обычно не имеет значения при отладке проблем управления памятью.Поскольку любое количество объектов каркаса могло сохранить объект для хранения ссылок на него, в то время как пулы автоматического выпуска могут содержать любое количество отложенных выпусков для объекта, маловероятно, что вы можете получить полезную информацию из этогоmethod.

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

Если вы действительно интересуетесь, почему это 3, вспомните, что:

  • Ссылкаиз вашего объекта DataMode a, скорее всего, будет удерживаться до тех пор, пока не будет истощен ближайший пул автоматического выпуска.выполняет некоторые - необычно необъяснимые - внутренние операции кэширования, так что вы можете увидеть несколько хранилищ, которые никто и не может объяснить
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...