Вопрос о распределении памяти - PullRequest
2 голосов
/ 20 июля 2011

У меня есть строка, которую я постоянно обновляю (~ 33 раза в секунду). Он используется снова и снова и снова и вездесущ в цикле, который я иду. Это цикл:

- (void)add{
    int r = (arc4random() % 30) + 51;
    long long debtInt = [debtString longLongValue];
    long long multiplier = r;
    long long debtAdj = multiplier + debtInt;
    debtString = [NSString stringWithFormat:@"%lli", debtAdj];
    [debtString retain];
    [self formating];
}

- (void)formating{
    NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
    [f setNumberStyle:NSNumberFormatterDecimalStyle];
    NSNumber * myNumber = [f numberFromString:debtString];
    [f release];

    NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
    [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
    [numberFormatter setMaximumFractionDigits:0];
    NSString *formattedNumberString = [numberFormatter stringFromNumber:myNumber];
    [numberFormatter release];

    UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 325, 100)];
    myLabel.font = [UIFont fontWithName:@"Verdana" size: 20.0];
    myLabel.text = formattedNumberString;
    myLabel.textAlignment = UITextAlignmentCenter;

    [self.view addSubview:myLabel];
    [myLabel release];
}

, который запускается NSTimer каждые 0,03 секунды. Единственное место, где я думал, что смогу логически высвободить debtString, было после того, как он был преобразован в длинное целое число. Это, однако, вылетает приложение. Если я удаляю строку [debtString retain], приложение вылетает.

Быстрое и быстрое наращивание памяти, это 14-байтовая строка. Каждую секунду, которая создает еще 462 байта неправильно распределенной памяти, что вместе со всеми настройками достигает примерно 3696 байт / сек. Это не утечка, которую я могу игнорировать. Я просто не знаю, где выпустить это в цикле!

Ответы [ 4 ]

4 голосов
/ 20 июля 2011

Если вы намерены сделать это таким образом, вы должны освобождать debtString на каждой итерации цикла, прямо перед тем, как переназначить значение:

[debtString release];    
debtString = [NSString stringWithFormat:@"%lli", debtAdj];
[debtString retain];

Однако каждый цикл вы создаете новый экземпляр. Вам лучше будет использовать один NSMutableString (как предложено @OscarMk) и обновлять его каждый раз. И не создавайте новый UILabel каждый раз. Просто создайте его и обновляйте содержимое каждый раз через цикл.

2 голосов
/ 20 июля 2011

Вы должны использовать NSMutableString специально, если он часто обновляется.

0 голосов
/ 21 июля 2011

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

0 голосов
/ 20 июля 2011

Когда вы используете stringWithNumber: метод, вы получаете строку, находящуюся в пуле автоматического выпуска.Они освобождаются, когда вы возвращаетесь к циклу событий.

Вместо этого используйте явное alloc и init:

[debtString release];  // release previous (if any)
debtString = [[NSString alloc] initWithFormat:@"%lli", debtAdj];

Если debtString - это @property, который сохраняется, это то, что делает установщикдля вас.

И с высоким содержанием кофеина это правильно, не создавайте новую UILabel каждый раз, просто обновите текстовое поле.То же самое для NSNumberFormatter, сохраните его как в переменной экземпляра, чтобы вам не приходилось каждый раз создавать его (а затем добавляйте его только в подпредставление).

...