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 Since you used stringWithString:
of a constant string just returns the string).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
精彩评论