我需要下载并解析 40mb 的 json。现在我正在使用 AFJSONRequestOperation,它在旧设备上会导致内存警告和崩溃。应该怎么做?我认为正确执行此操作的唯一方法是流式传输 json,但我不知道该怎么做或哪个库最好。请举例说明。非常感谢!
最佳答案
对于遇到相同问题的任何人,这是我解决它的方法: 1. 使用 AFHTTPRequestOperation 的输出流将 JSON 文件下载到本地存储。 2. 使用 YAJLParser 解析 NSData 的小块。
结果:我在 iPad (1) 上对 50mb json 进行了测试,没有任何内存警告(内存大约 10mb)。
例子:
NSError *error = nil;
NSData *data = [NSData dataWithContentsOfFile:path
options:NSDataReadingMappedAlways | NSDataReadingUncached
error:&error];
YAJLParser *parser = [[YAJLParser alloc] initWithParserOptions:YAJLParserOptionsAllowComments];
parser.delegate = self;
[parser parse:data];
parser.delegate = nil;
parser = nil;
YAJLParser 委托(delegate):
// first declare in header file NSMutableArray *stack and NSString *mapKey
- (void)parserDidStartDictionary:(YAJLParser *)parser
{
NSString *dictName = mapKey;
if (mapKey == nil)
{
dictName = (stack.count == 0) ? @"" : [stack lastObject];
}
[stack addObject:(dictName)];
}
- (void)parserDidEndDictionary:(YAJLParser *)parser
{
mapKey = nil;
[stack removeLastObject];
}
- (void)parserDidStartArray:(YAJLParser *)parser
{
NSString *arrayName = mapKey;
if (mapKey == nil)
{
arrayName = stack.count == 0 ? @"" : [stack lastObject];
}
[stack addObject:(arrayName)];
if([mapKey isEqualToString:@"something"])
{
// do something
}
}
- (void)parserDidEndArray:(YAJLParser *)parser
{
if([mapKey isEqualToString:@"some1"])
{
// do something
}
mapKey = nil;
[stack removeLastObject];
}
- (void)parser:(YAJLParser *)parser didMapKey:(NSString *)key
{
mapKey = key;
}
- (void)parser:(YAJLParser *)parser didAdd:(id)value
{
if([mapKey isEqualToString:@"id"])
{
// do something
}
}
关于iphone - iOS 巨大的 JSON (30MB) 处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18953977/