如果我在将第一个数组复制到第二个数组后释放它,我的应用程序就会崩溃。如果我自动释放第一个数组,一切正常。为什么?有没有更好的方法将第一个数组复制到第二个数组?
如果我调用这个方法,我会得到一个 ECX_BAD_ACCESS,我传递的是一个空数组
-(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;
}
如果我自动释放数组,它工作正常。
-(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];
}
最佳答案
让我们一步一步来
键:M = 释放/保留消息,C = 释放/保留消息的总和
// +----+---+
// | M | C |
// +----+---+
NSArray *array = [[NSArray alloc] initWithContentsOfFile:fp]; // | +1 | 1 |
details = array; // | 0 | 1 |
[array release]; // | -1 | 0 |
// +----+---+
此时您可以看到您将返回 details
其计数为 0 因此将已被释放 = 崩溃。复制是错误的术语,因为您实际上并不需要副本,因此您只需要指针
details
指向一个有效的对象,因此以下会更正确- (NSArray *)systemDetails
{
NSString *filePath = [self tempPathAndFileName:[self systemDetailsFileName]];
NSArray *details = [[[NSArray alloc] initWithContentsOfFile:filePath] autorelease];
if (!details) {
NSLog(@"No File to Load");
CreateSystem *cls = [[CreateSystem alloc] init];
details = [cls loadData];
[cls release]; cls = nil;
[self saveDataFile:details toPath:filePath];
}
NSLog(@"details: %@",details);
return details;
}
在这里,我正在利用 NSArray的方法initWithContentsOfFile:
...[returns] nil if the file can’t be opened or the contents of the file can’t be parsed into an array
这减少了一些麻烦并使该方法更易于阅读。我还将变量名称扩展为有意义的名称(个人喜好)。
我还将该方法重命名为
load
art 是多余的,因为本质上您正在返回系统详细信息,事实上它们正在被加载并不是方法调用者真正关心的问题。同样重要的是要注意,其他答案建议您进行额外的保留/复制,然后记得稍后释放返回的结果。这违反了 cocoa 约定,因为方法名称不包含 new/init/copy,因此该方法的调用者不应最终拥有结果。
关于objective-c - 为什么释放我的阵列会使我的应用程序崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8115644/