从应用程序中读取文件时,iPad应用程序崩溃且没有崩溃日志
我的程序的基本结构是用户从UITableView中选择一个项目,该项目与存储的文本文件相对应。然后将文件读入数组和字典中,其中数组有键(我知道我只能从字典本身获取键,这不是我的问题)。从应用程序中读取文件时,iPad应用程序崩溃且没有崩溃日志
然后,该视图将更改为UISplitView,其中主视图具有键,并且详细视图中包含词典中归因于该键的项目。在这种情况下,这是用户选择答案的一系列“是/否”问题。
我的问题是这样的:当我点击UITableView(第一个屏幕)中的单元格时,它工作正常,数据完全读取,等等。当我回到UITableView并再次单击相同的单元格时,程序崩溃。这里是读入,从文件的方法:
-(NSArray *)readFromFile:(NSString *)filePath{
// NSLog(@"Path was: %@", filePath);
NSString *file = [[NSString alloc] initWithContentsOfFile:filePath];
// NSLog(@"File was: %@", file);
NSScanner *fileScanner = [[NSScanner alloc] initWithString:file];
NSString *held;
NSString *key;
NSMutableArray *detailStrings;
NSMutableArray *keys = [[NSMutableArray alloc] init];
NSMutableDictionary *details = [[NSMutableDictionary alloc] init];
/**
This is where the fun stuff happens!
**/
while(![fileScanner isAtEnd]){
//Scan the string into held
[fileScanner scanUpToString:@"\r" intoString:&held];
NSLog(@"Inside the while loop");
// If it is a character, it's one of the Key points, so we do the management necessary
if ([[NSCharacterSet lowercaseLetterCharacterSet] characterIsMember:[[held lowercaseString] characterAtIndex: 0]]){
NSArray *checkers = [[NSArray alloc] initWithArray:[held componentsSeparatedByString:@"\t"]];
NSLog(@"Word at index 2: %@", [checkers objectAtIndex:2]);
if(detailStrings != nil){
[details setObject:detailStrings forKey:key];
[detailStrings release];
}
NSLog(@"After if statement");
key = [checkers objectAtIndex:2];
[keys addObject:(NSString *) key];
detailStrings = [[NSMutableArray alloc] init];
}
else if ([[NSCharacterSet decimalDigitCharacterSet] characterIsMember:[[held lowercaseString] characterAtIndex: 0]]){
NSArray *checkers = [[NSArray alloc] initWithArray:[held componentsSeparatedByString:@"\t"]];
NSLog(@"Word at index 1: %@", [checkers objectAtIndex:1]);
[detailStrings addObject:[checkers objectAtIndex:1]];
}
}
NSLog(@"File has been read in");
[details setObject:detailStrings forKey:key];
NSArray *contents = [[NSArray alloc] initWithObjects:(NSMutableArray *) keys, (NSMutableDictionary *) details, nil];
[detailStrings release];
return contents;
}
我已经确定
if(detailStrings != nil)
语句中的程序崩溃。我认为这是因为我错过了一些我应该做的内存管理,但没有知道错在哪里。关于这个问题的任何想法,或为什么它没有给我一个日志崩溃?
detailStrings
在您输入while
循环时未初始化。当您在方法内声明NSMutableArray *detailStrings;
时,detailStrings
不会自动设置为nil
。所以,当你做
if (detailStrings != nil) { .. }
进入if语句和,因为它没有初始化,当您访问detailStrings
它会崩溃。
另一件事是,如果detailStrings
首先进入else
部分,它将不会被初始化。这也会导致崩溃。因此,根据您的需要,无论是做
NSMutableArray *detailStrings = nil;
或您输入的while
循环之前进行初始化。
我很确定每个新定义的变量都会自动为零。您可以通过在定义后面放置一个断点来测试它,然后获取变量的值。它将等于0x0(零)。除非变量已经在其他地方使用 - 这就是为什么在不再需要时删除值不是一个坏主意(当代码中出现竞争条件时)。 –
只有当变量已经定义时才会出现问题 - 这可能就是这种情况。有人可能会说一个免费的指针。解决方案的确在分配'nil'。 –
@Randy Marsh:我知道一个事实,即Objective-C中新定义的变量不会自动为零。如果它们是类成员变量,它们是,因为'alloc'清除了它分配的内存,但是其他内存分配,比如像'detailStrings'这样的栈变量只是获得堆栈中发生的任何值。 – benzado
迪帕克说的是真话。你应该首先用nil初始化detailStrings。
但是还有第二个可能的问题:
我建议还发布后设置为零,因为在接下来的循环中,您可以测试与无记忆不存在的部分。
if(detailStrings != nil){
[details setObject:detailStrings forKey:key];
[detailStrings release];
detailStrings = nil;
}
而第三种可能的问题:从传入的数据可能会去的IF语句第一次,第二部分,并尝试ADDOBJECT成非初始化数组根据。
第四个(最后的希望):你有“跳棋”阵列
这里是我所看到的内存泄漏:
//read in the file
NSString *file = [[NSString alloc] initWithContentsOfFile:filePath];
//create the scanner
NSScanner *fileScanner = [[NSScanner alloc] initWithString:file];
//declare some uninitialized stuff
NSString *held;
NSString *key;
NSMutableArray *detailStrings;
//initialize some stuff
NSMutableArray *keys = [[NSMutableArray alloc] init];
NSMutableDictionary *details = [[NSMutableDictionary alloc] init];
//begin loop
while(![fileScanner isAtEnd]){
//scan up to a newline
[fileScanner scanUpToString:@"\r" intoString:&held];
//see if you scanned a lowercase string
if ([[NSCharacterSet lowercaseLetterCharacterSet] characterIsMember:[[held lowercaseString] characterAtIndex: 0]]){
//make an array
NSArray *checkers = [[NSArray alloc] initWithArray:[held componentsSeparatedByString:@"\t"]];
//do a check... against an uninitialized value
if(detailStrings != nil){
//set a potentially uninitialized value into an array with an uninitialized key
[details setObject:detailStrings forKey:key];
在这一点上,你几乎大清洗。
的修复:
- 正确初始化变量
- 运行静态分析
- 读取内存管理编程指南
现在阅读指南。感谢您的关注! – Althane
为什么你检查是否'detailStrings'是'nil' ?它显然是:你在if语句之前从来没有给它赋值。或者我错过了什么? –
调用堆栈或者崩溃的原因是什么? –
经过进一步的思考,我想你有一个释放的指针,'detailStrings'。重新定义它并不会使它成为'零'。 –