iOS巨大的JSON(30MB)处理

时间:2013-09-23 07:37:03

标签: iphone ios json ipad streaming

我需要下载并解析40mb的json。现在我正在使用AFJSONRequestOperation,它在旧设备上导致内存警告和崩溃。怎么做?我认为正确地做到这一点的唯一方法是流json,但我不知道如何做或者哪个库最好。请提供示例。非常感谢!

2 个答案:

答案 0 :(得分:4)

对于任何遇到同样问题的人,我的解决方法如下: 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代表:

// 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    
    }
}

答案 1 :(得分:2)

将数据写入文件,然后使用NSData的dataWithContentsOfFile:options:error:并指定NSDataReadingMappedAlways和NSDataReadingUncached标志。这将告诉系统使用mmap()来减少内存占用,而不是用内存块加载文件系统缓存(这会使速度变慢,但对iOS的负担要小得多)。

你可以在这里找到答案 iPad - Parsing an extremely huge json - File (between 50 and 100 mb)