开发者

Instruments says I'm leaking a string, but I can't find it

开发者 https://www.devze.com 2023-04-08 11:42 出处:网络
I used the leaks tool in Instruments to test the code, but the leaks tool cannot seem to find the leak.

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开发者_如何学JAVA",[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


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.


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


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

0

精彩评论

暂无评论...
验证码 换一张
取 消