保留的新发现,还是我的误解?

时间:2011-09-24 09:32:49

标签: iphone objective-c memory retain

@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

但代码不会泄漏任何内存。我得到泄漏和主动监控工具的结果。

开始我很惊讶

因为

SomeBody说“@property(保留)名字;”以下是相同的方法。

- getname
{
    return name;
}

如果那个.it无法解释上面的输出结果

我认为该方法应该如此

- getname
{
    [name retain];
    [name autorelease];
    return name;
}

所以这可以解释高数字7,而不是泄漏任何记忆。

这是我的猜测。我花了太多时间。我很惭愧。

我的理解是对的???欢迎您的帖子和评论。

4 个答案:

答案 0 :(得分:4)

“SomeBody”错了。来自The Objective-C Programming Language

  

如果您指定retaincopy但未指定nonatomic,那么   引用计数环境,一个合成的get访问器   object属性使用一个锁并保留并自动释放返回的   值 - 实现类似于以下内容:

[_internal lock]; // lock using an object-level lock
id result = [[value retain] autorelease];
[_internal unlock];
return result;
     

如果指定nonatomic,则对象属性的合成访问器只是直接返回值。

答案 1 :(得分:2)

1)retainCount对你没用。

2)retainCount对你没用。

3)是的,您的属性应该使用retain + autorelease(在某些情况下您可以违反此规则 - 我不会在此处详细说明)

- (NSString *)name { return [[name retain] autorelease];

(请注意,这也不是线程安全,也不是属性)

4)您的NSString属性应声明为copy(不是retain

5)您的initWithName:复制参数name_(假设该属性已被复制)

name = [name_ copy];

答案 2 :(得分:1)

鉴于您对环境不熟悉,您最有可能使用ARC并且根本不担心这种情况。

retainCount没用。不要打电话。

重复:

retainCount没用。不要打电话。

找到泄漏是没有用的,因为有更好,更准确,更少误导的工具。

您的代码存在一些问题(但泄漏不是其中之一):

  • NSString *属性应为copy

  • 您不使用该属性在init中设置字符串值,因此DataMode实例不会保留其字符串。

  • 没有dealloc方法

由于您使用了stringWithFormat:,因此常量字符串将变为非常量字符串。如果您使用了常量字符串或stringWithString:,那就是abazillionsomething(unsigned -1 ... UINT_MAX ...)。

无论如何,你有:

  • +1 stringWithString:
  • +1,每次调用时都会调用a.name

如果Instruments声称泄漏,请发布屏幕截图。

答案 3 :(得分:-2)

您应该输入

- initWithName:(NSString * )name_
{
    self = [super init];

    if (self != nil)
    {
        name = name_;
    }
    return self;
}