我在玩弄戴夫·德龙的优秀的objective-cCHCSVParser,它有一个非常长的.csv文件,在使用它时遇到了一些麻烦。我会使用arrayWithContentsOfCSVFile方法,但是我在iPhone上运行代码,把整个文件解析成内存会占用比可用内存更多的内存。
在下面的代码中,解析器打开文档并完美地调用委托方法,但是在委托中,我应该在每一行之后停止并访问数据(以创建核心数据对象并将其保存到数据存储区)?我假设它在- (void) parser:(CHCSVParser *)parser didEndLine:(NSUInteger)lineNumber中,但是当解析器处理完这一行时,如何从解析器中获取数据的NSArray(或其他内容)?
这是我目前的代码:

//
// The code from a method in my view controller:
//
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSFileManager *manager = [NSFileManager defaultManager];
NSError *err = nil;
NSArray *fileList = [manager contentsOfDirectoryAtPath:documentsDirectory error:&err];
NSString *fileName = [fileList objectAtIndex:1];
NSURL *inputFileURL = [NSURL fileURLWithPath: [documentsDirectory stringByAppendingPathComponent:fileName]];


NSStringEncoding encoding = 0;
CHCSVParser *p = [[CHCSVParser alloc] initWithContentsOfCSVFile:[inputFileURL path] usedEncoding:&encoding error:nil];
[p setParserDelegate:self];
[p parse];
[p release];

...

#pragma mark -
#pragma mark CHCSVParserDelegate methods

- (void) parser:(CHCSVParser *)parser didStartDocument:(NSString *)csvFile {
    NSLog(@"Parser started!");
}

- (void) parser:(CHCSVParser *)parser didStartLine:(NSUInteger)lineNumber {
    //NSLog(@"Parser started line: %i", lineNumber);
}

- (void) parser:(CHCSVParser *)parser didEndLine:(NSUInteger)lineNumber {
    NSLog(@"Parser ended line: %i", lineNumber);
}

- (void) parser:(CHCSVParser *)parser didReadField:(NSString *)field {
    //NSLog(@"Parser didReadField: %@", field);
}

- (void) parser:(CHCSVParser *)parser didEndDocument:(NSString *)csvFile {
    NSLog(@"Parser ended document: %@", csvFile);
}

- (void) parser:(CHCSVParser *)parser didFailWithError:(NSError *)error {
    NSLog(@"Parser failed with error: %@ %@", [error localizedDescription], [error userInfo]);
}

谢谢!

最佳答案

我很高兴看到我的代码被证明是有用的!:)
CHCSVParser在行为上类似于NSXMLParser,因为每当它发现有趣的东西时,它会通过一个委托回调让你知道。但是,如果你选择忽略它在回调中给你的数据,那么它就消失了。这些解析器(CHCSVParserNSXMLParser)是相当愚蠢的。他们只知道他们试图解析的内容的格式,但除了这些,他们并没有做什么。
所以,简而言之,答案是“你必须自己拯救它”。如果您查看了NSArray类的代码,您将在.m文件中看到它使用的是“AA>”,而子类是将字段聚合到一个数组中,然后将该数组添加到整个数组中。你需要做一些类似的事情。
代理示例:

@interface CSVParserDelegate : NSObject <CHCSVParserDelegate> {
  NSMutableArray * currentRow;
}
@end

@implementation CSVParserDelegate

- (void) parser:(CHCSVParser *)parser didStartLine:(NSUInteger)lineNumber {
  currentRow = [[NSMutableArray alloc] init];
}
- (void) parser:(CHCSVParser *)parser didReadField:(NSString *)field {
  [currentRow addObject:field];
}
- (void) parser:(CHCSVParser *)parser didEndLine:(NSUInteger)lineNumber {
  NSLog(@"finished line! %@", currentRow);
  [self doSomethingWithLine:currentRow];
  [currentRow release], currentRow = nil;
}
@end

但是,我可以确信修改解析器的行为来聚集行本身,但是如果我沿着该路径走下去,为什么不让解析器聚合整个文件呢?(回答:不应该)

10-07 14:57