views:

52

answers:

2

I created an NSScanner category method that shows a leak in instruments.


- (BOOL)scanBetweenPrefix:(NSString *)prefix 
                andSuffix:(NSString *)suffix 
               intoString:(NSString **)value
{
    NSCharacterSet *charactersToBeSkipped = [self charactersToBeSkipped];
    [self setCharactersToBeSkipped:nil];

    BOOL result = NO;

    // find the prefix; the scanString method below fails if you don't do this
    if (![self scanUpToString:prefix intoString:nil])
    {
        MY_LOG(@"Prefix %@ is missing.", prefix);
        return result;
    }

    //scan the prefix and discard
    [self scanString:prefix intoString:nil];

    // scan the important part and save it
    if ([self scanUpToString:suffix intoString:value]) // this line leaks
    {
        result = YES;
    }
    [self setCharactersToBeSkipped:charactersToBeSkipped];
    return result;
}

I figure it's the way I'm passing the value to/from the method, but I'm not sure. It's a small leak (32 bytes), but I'd like to do this right if I can. Thanks in advance.

A: 
jluckyiv
Given where the leaking memory was allocated, the most likely explanation is that however you are using title after this code, you are leaking that string.
smorgan
jluckyiv: I see nothing wrong in either the category method or this use of it. Look at the history of the `title` object's address in Instruments to see what has retained it and failed to release it.
Peter Hosey
Peter, thanks for the advice. I'm still finding my way around Instruments.
jluckyiv
+2  A: 

I found the answer. I had a model class that used the result of the code above, but forgot to release the property in the dealloc method. I should have caught it with Instruments, but I didn't know where to look. I got caught up in the call stack in the Extended Details, which had only part of the info I needed.

For morons like me, here's what I did:

  1. Run your app with Instruments ... Leaks.
  2. In Instruments, watch the leaked blocks view (the grid icon at the bottom) and turn on the extended detail.
  3. If you have multiple leaked objects, click the disclosure triangle so you can look at a discrete address.
  4. Next to an address, there will be a detail arrow. Click on it.
  5. Now you'll be looking at history. It starts with Malloc and shows you each retain and release.

You should have a release for the malloc and a release for every retain in the history. Match up your retains and releases and look for the oddball. When in doubt, look toward the bottom of the page and carefully review any properties you may have forgotten to release in your dealloc method(s).

jluckyiv
+1 Good description of how to use Leaks for beginners.
Rob Keniger