If I release my first array after I copied it to the second array my app crashes. If I autorelease the first array everything works fine. Why? Is there a better way to copy the first array to the second array?
If I call this method I get a ECX_BAD_ACCESS, I am passing an empty array
-(NSArray *)loadSystemDetails
{
AssortedCodeSnippets *acs = [[AssortedCodeSnippets alloc] init];
NSArray *details;
NSString *fp = [self tempPathAndFileName:[self systemDetailsFileName]];
if ([acs fileExistsAtPath:fp]) {
NSArray *array = [[NSArray alloc] initWithContentsOfFile:fp];
details = array;
[array release];
} else {
NSLog(@"No File to Load");
CreateSystem *cls = [[CreateSystem alloc] init];
details = [cls loadData];
[cls release];
[self saveDataFile:details toPath:fp];
}
NSLog(@"details: %@",details);
[acs release];
return details;
}
If I autorelease array it work fine.
-(NSArray *)loadSystemDetails
{
AssortedCodeSnippets *acs = [[AssortedCodeSnippets alloc] init];
NSArray *details;
NSString *fp = [self tempPathAndFileName:[self systemDetailsFileName]];
if ([acs fileExistsAtPath:fp]) {
NSArray *array = [[[NSArray alloc] initWithContentsOfFile:fp]autorelease];
details = array;
} else {
NSLog(@"No File to Load");
CreateSystem *cls = [[CreateSystem alloc] init];
details = [cls loadData];
[cls release];
[self saveDataFile:details toPath:fp];
}
Let’s step through this
Key: M = release/retain message, C = sum of the release/retain messages
At this point you can see that you are going to be returning
detailswhich has a count of 0 therefore will have been deallocated already = crash.Copy is the wrong term as you do not actually need a copy as such you just want your pointer
detailsto point to a valid object therefore the following would be more correctHere I am taking advantage of NSArray‘s method
This cuts down some of the cruft and makes the method a bit easier to read. I also expanded the variable names to meaningful names (personal preference).
I have also renamed the method as the
loadart is superflous as essentially you are returning the system details the fact that they are being loaded is not not really a concern to the caller of the method.It’s also important to note that the other answers suggest that you take an additional retain/copy and then remember to release the returned result later on. This goes against cocoa convention as the method name does not contain new/init/copy therefore the callers f the method should not end up owning the result.