为什么需要保留 NSString 变量?

发布于 2024-10-16 08:47:02 字数 713 浏览 3 评论 0原文

我的 .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< /em> 如果它已经定义为(非原子,保留)? 如果我不添加 [dPath keep];在其他函数中使用此变量时,我遇到一些奇怪的随机错误,并且应用程序崩溃。我想这是因为某些地方有一些自动释放,但我没有。

那么,(非原子,retain)到底在做什么呢? [dPath keep] 真的有必要吗?或者我只是隐瞒了其他事情?

I have the following code in my .h file:

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

And in my .m file:

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

Why do I have to retain dPath if it's already defined as (nonatomic, retain)?
If I don't add the [dPath retain]; I get some strange, random errors and the application crashes when using this variable in other functions. I guess that's because of some autorelease somehere but I don't have any.

So, what is the (nonatomic, retain) doing anyway? Is it really necessary the [dPath retain]; or am I just hiding something else with that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

予囚 2024-10-23 08:47:02

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

dPath = [[documentPaths objectAtIndex:0] stringByAppendingPathComponent:kDatabaseName];
[dPath 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 方法,以及直接引用实例变量的任何其他代码,请改为使用附加名称:

- (void)dealloc {
    [dPath_ release];

    [super dealloc];
}

Because the code isn't calling the dPath property's setter method, it's just setting the instance variable dPath directly:

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

So it has to be retained manually.

You will be able to (in fact you need to) omit the retain call if the property setter was used like this (notice the self.):

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

or like this (notice the setDPath:):

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

The setter retains the NSString for you so you don't have to do it yourself.


A nice little practice to follow in order to avoid the confusion, is to affix an underscore to your ivar name to indicate it's an ivar:

    NSString *dPath_;

Then synthesize your property like this, to associate it with your differently-named ivar:

// self.dPath is the property, dPath_ is the ivar
@synthesize dPath = dPath_;

Then modify your dealloc method, as well as any other code that directly references the instance var, to use the affixed name instead:

- (void)dealloc {
    [dPath_ release];

    [super dealloc];
}
我还不会笑 2024-10-23 08:47:02

尝试设置并获取它

self.dPath

try setting and getting it with

self.dPath
何处潇湘 2024-10-23 08:47:02

如果您想调用属性 setter 方法,该方法将调用保留,那么您需要编写:

self.dPath = ...

将内容塞入变量中:

dPath = ...

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

If you want to call the property setter method, which will invoke the retain, then you want to write:

self.dPath = ...

Jamming stuff into a variable with:

dPath = ...

completely ignores the properties of this instance variable. Which is why you ended up needing to do the retain manually.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文