Take the 2-minute tour ×

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.

share|improve this question
How did you call this method? How did you prepare (NSString**) value when you called it? –  Yuji Mar 17 '10 at 13:53
Yuji, thanks for the response. I can't format code in the comment, so see my answer below. –  jluckyiv Mar 17 '10 at 14:00
add comment

2 Answers

up vote 2 down vote accepted

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).

share|improve this answer
+1 Good description of how to use Leaks for beginners. –  Rob Keniger Mar 18 '10 at 23:35
add comment

OK, I'm stupid. This method does not leak. The leak is farther down my call stack, but I can't figure out where. Sorry for the premature post. I'll follow up when I figure out where the real leak is, if I can't figure out the fix myself.

In answer to Yuji's comment, my method call is:

    NSString *title;
    [fileScanner scanBetweenPrefix:kTitlePrefix 

Is it the &title that's the problem? I patterned it after the existing NSScanner methods and calls.

share|improve this answer
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 Mar 17 '10 at 14:26
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 Mar 17 '10 at 20:05
Peter, thanks for the advice. I'm still finding my way around Instruments. –  jluckyiv Mar 17 '10 at 20:46
add comment

Your Answer


