Нужна помощь в устранении утечки памяти - NSMutableString

Играл с инструментами, но без особого успеха в выяснении, как решить эту утечку памяти.

Во-первых, код:

-(NSString *) randomizeHint:(NSString *) wordToShuffle{

    NSMutableString * outputstring = [NSMutableString stringWithCapacity:[wordToShuffle length]];
    NSMutableSet * usedNumberSet = [NSMutableSet setWithCapacity:[wordToShuffle length]];

    for (int i=0; i<[wordToShuffle length]; i++) {
        int randomnum = arc4random()%[wordToShuffle length];

        while ([usedNumberSet containsObject:[NSNumber numberWithInt:randomnum]]==YES) {
            randomnum = arc4random()%[wordToShuffle length];
        }

        [usedNumberSet addObject:[NSNumber numberWithInt:randomnum]];
        [outputstring appendFormat:@"%c",[wordToShuffle characterAtIndex:randomnum]];
    }

    CCLOG(@"outputstring is:%@",outputstring);
    return outputstring;

 }

Инструменты дают мне следующее:

Leaked Object = NSCFString, Responsible Library = Foundation, Responsible Frame = -[NSPlaceholderMutableString initWithCapacity:]

Любые идеи?

Заранее спасибо.


person prazzledazzle    schedule 16.07.2012    source источник
comment
Код кажется правильным. И в этом случае NSMutableString выпускается автоматически. Вы уверены, что эта утечка происходит в приведенном выше коде?   -  person Inder Kumar Rathore    schedule 16.07.2012
comment
Попробовать return [outputstring copy]?   -  person ZhangChn    schedule 16.07.2012
comment
Мне кажется, что если вы протечете где-нибудь объект, Instruments укажет обратно на то место, где он был создан. Может быть, вызывающий эту подпрограмму пропускает возвращаемую строку?   -  person Phillip Mills    schedule 16.07.2012
comment
Спасибо за комментарии, ребята. InderKumarRathore - я думал, что NSMutableString тоже был выпущен автоматически, поэтому поставил в тупик. ZhangChn - я не хочу явно выпускать его вне этого метода, это локальная переменная, поэтому копия не сделает этого за меня. Филлипс Миллс - Да, к сожалению, это последний элемент трассировки стека в моем коде перед тем, как инструменты уйдут в стандартные библиотеки.   -  person prazzledazzle    schedule 17.07.2012


Ответы (2)


Вам действительно не нужно использовать изменяемую строку ... тем более, что ваш возвращаемый тип - NSString. Просто используйте stringByAppendingFormat:

-(NSString *) randomizeHint:(NSString *) wordToShuffle{

    NSString * outputstring = @"";

    NSMutableSet * usedNumberSet = [NSMutableSet setWithCapacity:[wordToShuffle length]];

    for (int i=0; i<[wordToShuffle length]; i++) {
        int randomnum = arc4random()%[wordToShuffle length];

        while ([usedNumberSet containsObject:[NSNumber numberWithInt:randomnum]]==YES) {
            randomnum = arc4random()%[wordToShuffle length];
        }

        [usedNumberSet addObject:[NSNumber numberWithInt:randomnum]];

        // just set outputstring like so... no need to worry about a leaky mutable string then
        outputstring = [outputstring stringByAppendingFormat:@"%c",
                    [wordToShuffle characterAtIndex:randomnum]];
    }


    return outputstring;

}
person jerrylroberts    schedule 16.07.2012
comment
+1 для лучшего поведения (т.е. по возможности избегать изменчивых). Кроме того, если ваша утечка находится в этом разделе кода, это, вероятно, поможет. Утечка NSString объектов действительно затруднена. - person ravron; 16.07.2012
comment
Я попробую и вернусь к вам. Спасибо за помощь. - person prazzledazzle; 17.07.2012
comment
Были времена, когда я думал, что мне нужна NSMutableString, и каждый раз позже мне приходилось реорганизовывать ее. Рад, что смог помочь! - person jerrylroberts; 17.07.2012

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

person YvesLeBorg    schedule 16.07.2012