我的程序的基本结构让用户从UITableView中选择一个项目,该项目对应于存储的文本文件。然后将该文件读入数组和字典,其中数组具有键(我知道我可以从字典本身获取键,这不是我的问题)。
然后将视图更改为UISplitView,其中主视图具有键,详细视图将字典中的项目归因于该键。在这种情况下,它是用户选择答案的一系列“是/否”问题。
我的问题是这样的:当我点击UITableView(第一个屏幕)中的一个单元格时,它工作正常,数据被完美读取,依此类推。当我回到UITableView并再次单击同一个单元格时,程序崩溃了。这是文件中的read-in-file方法:
-(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)
语句。我认为这是因为我错过了一些我本应该做的内存管理,但是不知道它出了什么问题。关于问题的任何想法,或者为什么在不给我日志的情况下崩溃?
答案 0 :(得分:3)
detailStrings
循环时, while
未初始化。当您在方法中声明NSMutableArray *detailStrings;
时,detailStrings
不会自动设置为nil
。所以当你这样做时
if ( detailStrings != nil ) { .. }
它进入if语句,因为它没有被初始化,所以当你访问detailStrings
时它会崩溃。
另一件事是detailStrings
如果首先进入循环的else
部分,则不会被初始化。那也会导致崩溃。因此,根据您的要求,要么
NSMutableArray *detailStrings = nil;
或在您输入while
循环之前对其进行初始化。
答案 1 :(得分:2)
但还有第二个可能的问题:
我建议在发布后设置nil,因为在下一个循环中你可以用nil测试不存在的内存部分。
if(detailStrings != nil){
[details setObject:detailStrings forKey:key];
[detailStrings release];
detailStrings = nil;
}
第三个可能的问题:根据传入的数据,你可能会第一次进入IF语句的第二部分并尝试将addObject添加到非初始化的数组中。
第四个(希望最后):你有“checkers”数组的内存泄漏
答案 2 :(得分:1)
这就是我所看到的:
//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];
在这一点上,你几乎已经被冲洗了。
修复: