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?
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];
}