为什么需要保留NSString变量?

时间:2011-02-05 06:34:09

标签: iphone objective-c nsstring retain autorelease

我的 .h 文件中包含以下代码:

@interface Utils : NSObject {
    NSString *dPath;
}    
@property(nonatomic, retain) NSString *dPath;

在我的 .m 文件中:

    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
dPath = [[documentPaths objectAtIndex:0] stringByAppendingPathComponent:kDatabaseName];
[dPath retain]; 

如果已经定义为(非原子,保留),为什么必须保留 dPath ? 如果我不添加[dPath retain];我得到一些奇怪的,随机的错误,并且在其他函数中使用此变量时应用程序崩溃。我想那是因为某些 autorelease 某处,但我没有。

那么,什么是(非原子的,保留)呢?是否真的有必要[dPath保留];或者我只是隐藏其他东西?

3 个答案:

答案 0 :(得分:7)

因为代码没有调用dPath属性的setter方法,所以它只是直接设置实例变量dPath

dPath = [[documentPaths objectAtIndex:0] stringByAppendingPathComponent:kDatabaseName];
[dPath retain]; 

因此必须手动保留。

如果像这样使用属性设置器(注意retain),你将能够(事实上你需要)省略self.调用:

self.dPath = [[documentPaths objectAtIndex:0] stringByAppendingPathComponent:kDatabaseName];

或者像这样(注意setDPath:):

[self setDPath:[[documentPaths objectAtIndex:0] stringByAppendingPathComponent:kDatabaseName]];

setter会为你保留NSString,所以你不必自己动手。


为了避免混淆,要遵循一个很好的小练习,就是在你的ivar名称上加上一个下划线,表明它是一个ivar:

    NSString *dPath_;

然后像这样合成你的属性,将它与你的不同命名的ivar:

联系起来
// self.dPath is the property, dPath_ is the ivar
@synthesize dPath = dPath_;

然后修改您的dealloc方法以及直接引用实例var的任何其他代码,以改为使用附加名称:

- (void)dealloc {
    [dPath_ release];

    [super dealloc];
}

答案 1 :(得分:0)

尝试设置并使用

进行设置
self.dPath

答案 2 :(得分:0)

如果要调用属性setter方法,它将调用retain,那么你想写:

self.dPath = ...

使用以下内容将内容编入变量:

dPath = ...

完全忽略此实例变量的属性。这就是为什么你最终需要手动保留。