开发者

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 or copy and do not specify nonatomic, 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;
}
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜