new discovery of retain ,or my misunderstanding?
@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
{
NSString * str = [NSString stringWithFormat:@"zhang"];
DataMode * a = [[DataMode alloc] initWithName:str];
a.name;
a.name;
a.name;
a.name;
a.name;
NSLog(@"name count:%d",[a.name retainCount]);
[ a release];
NSLog(@"str count:%d",[str retainCount]);
}
@end
the output is
name count:7
str count:7
but the code don'开发者_运维百科t leak any memory. I get the result in leaks and Active monitor tools.
begin I am surprise
because
SomeBody say "@property (retain) name;" eaual the below equal method.
- getname
{
return name;
}
if that .it can't explain the above reslut of the output
I think the method should so
- getname
{
[name retain];
[name autorelease];
return name;
}
so this can explain the high number 7,and not leak any memory.
this is my guess . it take me too much time .I am shamed.
My understanding is right ??? welcome your post and comment.
"SomeBody" is wrong. From The Objective-C Programming Language:
If you specify
retain
orcopy
and do not specifynonatomic
, then in a reference-counted environment, a synthesized get accessor for an object property uses a lock and retains and autoreleases the returned value—the implementation will be similar to the following:[_internal lock]; // lock using an object-level lock id result = [[value retain] autorelease]; [_internal unlock]; return result;
If you specify
nonatomic
, a synthesized accessor for an object property simply returns the value directly.
1) retainCount
is useless to you.
2) retainCount
is useless to you.
3) yes, your properties should use retain+autorelease (there are a few cases where you can break this rule -- i'll not detail them here)
- (NSString *)name { return [[name retain] autorelease];
(note that this also is not threadsafe, nor are properties)
4) your NSString properties should be declared copy
(not retain
)
5) your initWithName:
should copy the argument name_
(assuming the property is copied)
name = [name_ copy];
Given that you are new to the environment, you should most likely be using ARC and not worrying about this kind of stuff at all.
retainCount is useless. Don't call it.
To repeat:
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
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
, every time it is called
If Instruments is claiming a leak, post a screenshot.
You shold type
- initWithName:(NSString * )name_
{
self = [super init];
if (self != nil)
{
name = name_;
}
return self;
}
精彩评论