Need help fixing memory leak - NSMutableString

2019-08-31 08:57发布

问题:

Have been playing around with instruments with not much luck in figuring out how to solve this memory leak.

Firstly the code:

-(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;

 }

Instruments is giving me the following:

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

Any ideas?

Thanks in advance.

回答1:

You don't really need to use a mutable string... especially since your return type is NSString. Just use 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;

}


回答2:

Look at where the returned string is used. Possibly you are retaining it and dealloc'ing the object that retained the string without first releasing the retained string. Instruments will still point to this section of code as being the 'leaked' object. The hardest part is locating the 'leaker'. And yes, you can leak a string, I just wrote the recipe for it.