2013-09-23 81 views
3

我需要下載並解析40mb的json。現在我正在使用AFJSONRequestOperation,它在較舊的設備上導致內存警告和崩潰。應該怎麼做?我認爲正確地做到這一點的唯一方法是將json流式傳輸,但我不知道如何去做,或者哪​​個庫最好。請提供例子。非常感謝!iOS巨大的JSON(30MB)處理

回答

4

任何人回答誰擁有了同樣的問題,這裏是我如何解決它:使用AFHTTPRequestOperation的輸出流 1.下載JSON文件下載到本地存儲。 2.使用YAJLParser解析NSData的小塊。

結果:我在iPad上測試了50mb json(1),沒有任何內存警告(內存大約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  
    } 
} 
2

將數據寫入文件,然後使用NSData的dataWithContentsOfFile:options:error:並指定NSDataReadingMappedAlways和NSDataReadingUncached標誌。這將告訴系統使用mmap()來減少內存佔用量,而不是用內存塊(這使得它更慢,但對iOS的負擔更小)給文件系統緩存帶來負擔。

您可以在這裏找到 iPad - Parsing an extremely huge json - File (between 50 and 100 mb)

+0

的NSData *數據= [NSData的dataWithContentsOfFile:路徑選擇:NSDataReadingMappedAlways | NSDataReadingUncached error:&error]; NSDictionary * dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];現在它試圖創建NSDictionary時崩潰。 – Wojczitsu

+0

可能它不是nsdictionary,它是一個數組 – incmiko

+0

不,它不是。這是內存崩潰。 – Wojczitsu