0

I used the leaks tool in Instruments to test the code, but the leaks tool cannot seem to find the leak.

At the end of my code, the output of NSLog(@"str count:%d",[str retainCount]); is 3. Why? I don't override the dealloc. [a.name retainCount] is there just one time and I only autorelease str for one time. So str shouldn't leak.

@interface DataMode : NSObject {

    NSString * name;
}

@property (retain) NSString * name;

- initWithName:(NSString * )name_;
@end


@implementation DataMode

@synthesize name;

- initWithName:(NSString * )name_
{
    if ([super init] != nil)
    {
        name = name_;
        return self;
    }
    return nil;
}

@end


- (void) pressed:(id)sender
{
    for( int i = 0;i<10000000;i++)
    {
        NSString * str = [NSString stringWithFormat:@"zhang"];
        DataMode * a = [[DataMode alloc] initWithName:str];
        NSLog(@"a0 count:%d",[a retainCount]);
        NSLog(@"name1 count:%d",[a.name retainCount]);
        NSLog(@"name1 count:%d",[a.name retainCount]);
        NSLog(@"a1 count:%d",[a retainCount]);
        [ a  release];
        NSLog(@"str count:%d",[str retainCount]);
        NSLog(@"str count:%d",[str retainCount]);
    }


}
@end
yuji
  • 16,695
  • 4
  • 63
  • 64
user961298
  • 11
  • 2

3 Answers3

3

retainCount is useless. Don't call it.

It is not useful for finding leaks as there are much better, more accurate, and less misleading tools available.

There are several problems with your code (but leaking isn't one of them):

  • NSString* properties should be copy

  • you don't use the property to set the string value in init, thus the DataMode instances are not retaining their strings.

  • there is no dealloc method

As for the retain counts; I'm surprised it is "3". I'd expect it to be 2bazillionsomething as that is a constant string (and stringWithString: of a constant string just returns the string).Since you used stringWithFormat:, the constant string is turned into a non-constant string. If you had used the constant string or stringWithString:, it'd be abazillionsomething (unsigned -1... UINT_MAX...).

In any case, you have:

  • +1 for stringWithString:
  • +1 for calling a.name
  • +1 for calling a.name

+3 overall.

If Instruments is claiming a leak, post a screenshot.

bbum
  • 162,346
  • 23
  • 271
  • 359
  • It’s not a constant string because the OP used `+stringWithFormat:`… and without a format, heh. –  Sep 23 '11 at 16:23
  • Oh, derp. Right. `stringWithString:` does that. `stringWithFormat:` doesn't bother (though it could). – bbum Sep 23 '11 at 17:07
  • i think it should have leaks. tools can't find it. because [a.name retainCount] add 1 ,But I dont't release it. thus I don't use ARC. – user961298 Sep 24 '11 at 03:45
  • i think it should have leaks. tools can't find it. because [a.name retainCount] add 1 ,But I dont't release it.The count of str is 3. I only autorelease it a time. thus I don't use ARC. – user961298 Sep 24 '11 at 03:57
0

I quote the NSObject protocol reference for -retainCount:

This method is typically of no value in debugging memory management issues. Because any number of framework objects may have retained an object in order to hold references to it, while at the same time autorelease pools may be holding any number of deferred releases on an object, it is very unlikely that you can get useful information from this method.

The retain count could be 3 for any number of reasons; if you can't find a leak with the leaks tool, it's likely you don't have a leak. Don't worry about the actual value of the retain count.

If you're really interested in why it's 3, recall that:

  • The reference from your DataMode object a will likely be held until the closest autorelease pool is drained
  • You're still holding a reference in the str variable
  • The NSString class cluster, among others, does some - unusually inexplicable - caching things internally, so you may see a few retains here and there for which nobody can account
Tim
  • 59,527
  • 19
  • 156
  • 165
  • almost right on where the retains are coming from.... The DataMode object's presence in an autorelease pool wouldn't affect the retain count of the string. – bbum Sep 23 '11 at 16:14
  • The code is confusing; DataMode isn't retaining the string ever given the way the rest of the code is written. It is wrong. – bbum Sep 25 '11 at 01:51
0

Since you are using the convenience method to create str which is autoreleased you will not see determinate behavior using retain counts in this way.

Check my response to another question and add those methods to DataMode and you should see when the framework releases your objects from the autorelease pool.

Overriding release and retain in your class

Community
  • 1
  • 1
EricLeaf
  • 892
  • 5
  • 12