iphone - 如何使用 CHCSVParser 类

标签 iphone objective-c core-data csv

我正在玩 Dave DeLong 的优秀 CHCSVParser对于带有超长 .CSV 文件的 Objective-C,我在使用它时遇到了一些麻烦。我会使用 arrayWithContentsOfCSVFile 方法,但我在 iPhone 上运行代码并将整个文件解析到内存中会占用比可用内存更多的内存。

在我下面的代码中,解析器打开文档并完美地调用委托(delegate)方法,但是我在委托(delegate)中的每一行之后停止并访问数据(以创建核心数据对象并将其保存到数据存储)?我假设那将在 - (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 相似,因为每次它发现有趣的东西时,它都会通过委托(delegate)回调之一通知您。但是,如果您选择忽略它在回调中提供给您的数据,那么它就会消失。这些解析器(CHCSVParserNSXMLParser)非常愚蠢。他们只知道他们试图解析的内容的格式,但除此之外并没有做太多事情。

因此,简而言之,答案是“您必须自己保存”。如果您查看 NSArray 类别的代码,您会在 .m 文件中看到它使用了 a simple NSObject subclass as the parser delegate。 ,该子类将字段聚合到一个数组中,然后将该数组添加到整个数组中。您需要做类似的事情。

示例委托(delegate):

@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

然而,我可以说服修改解析器的行为以聚合行本身,但如果我沿着这条路走,为什么不让解析器聚合整个文件呢? (答案:不应该)

关于iphone - 如何使用 CHCSVParser 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3788295/

相关文章:

json - CollectionView.reloadData() 以错误的顺序输出单元格

iphone - 等待键盘隐藏

iphone - 如何监控我的应用程序消耗了多少内存?

ios - 当我在不使用 performSegueWithIdentifier 的情况下单击按钮时,不会调用 prepareForSegue

ios - 如何忽略 NSManagedObjectContextWillSaveNotification 中 mergeChangesFromContextDidSaveNotification 的变化

ios - 关于与主应用程序共享核心数据上下文的应用程序扩展编程指南

iphone - 在 Cocos2d 中更改多个 Sprite 的不透明度

iphone - AWS S3 Bucket - 使用 AWS SDK 将文件添加到内部文件夹

objective-c - 打开一个新窗口并等待它关闭

ios - 获取CABasicAnimation的即时值