0

多くの JSON 文字列を解析したい。コードは次のとおりです。

while(stations.count > 0) {
        NSString*string = [[[NSString alloc] initWithString:[stations objectAtIndex:0]] retain];
        
        NSMutableDictionary*dic = [[[NSMutableDictionary alloc]init]retain];
        
        NSData*data = [[[NSData alloc] initWithData:[string dataUsingEncoding:NSUTF8StringEncoding]]retain];
        NSMutableDictionary* pars = [[NSMutableDictionary alloc]initWithDictionary:[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]];
        
        [dic setObject:[NSString stringWithString:[pars objectForKey:@"nm"]] forKey:@"nm"];
        [dic setObject:[NSString stringWithString:[pars objectForKey:@"btr"]] forKey:@"btr"];
        [dic setObject:[NSString stringWithString:[pars objectForKey:@"id"]] forKey:@"id"];
        [dic setObject:[NSString stringWithString:[pars objectForKey:@"cntr"]] forKey:@"cntr"];
        [dic setObject:[NSString stringWithString:[pars objectForKey:@"gnr"]] forKey:@"gnr"];
        
        [pars release];
        @try {
            [parsedData addObject:[NSDictionary dictionaryWithDictionary:dic]];
        }
        @catch (NSException* exc) {
            NSLog(@"%@, %@", exc.description, exc.reason);
        }
        [dic release];
        [data release];
        [string release];
        [stations removeObjectAtIndex:0];
        
        if (i%1000==0) {
            NSLog(@"nnnn %i %i", parsedData.count, stations.count);
        }
        
        i++;
        float k = count;
        k = (i + 1)/k;
        
        [self performSelectorOnMainThread:@selector(increaseProgress:) withObject:[NSNumber numberWithFloat:k] waitUntilDone:YES];
    }

(通常は毎回ではありませんが)文字列を配列に追加すると、エラーが発生します:

exc_breakpoint (コード=exc_i386_bpt

と:

GuardMalloc [Radiocent new try-1820]: VM の割り当てに失敗しました 68752 バイト

GuardMalloc[Radiocent new try-1820]: 明示的にデバッガーにトラップ!!!

Stations 配列はかなり大きいです...約 60000 文字列です。

4

1 に答える 1

0

まず、割り当て時に保持カウントが既に +1 であるため、保持する必要はありません。

NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];

いいえ

NSMutableDictionary*dic = [[[NSMutableDictionary alloc]init]retain];

以下の行はすでに変更可能な辞書を返しているため、そこから新しい辞書を作成する必要はありません。変更したい場合は、-mutableCopy を呼び出すだけです。

NSMutableDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];

またはコピーを作成するには:

NSMutableDictionary *dictionary = [[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil] mutableCopy];

ステーションが JSON 文字列の場合、すべてのステーションに対して次のようにします。

NSData *data = [JSONString dataUsingEncoding:NSUTF8StringEncoding];
NSArray *stationsArray = [[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil] mutableCopy];

for (NSDictionary *stationDic in stationArray)
{
     // This will iterate over each station dictionary in the station array
     // Do your stuff here ...
}

あなたの例:(二重引用符をエスケープするために \" を追加しましたが、する必要はありません)

例の周りに角括弧を配置すると、配列になり、以下のコードを使用してそれぞれを反復処理できます。(無い場合のみ追加)

NSString *example = @"[{\"id\":\"02AB99\",\"btr\":\"24\",\"cntr\":\"461E\",\"gnr\":\"8A51\",\"nm\":\"88.3 Fm Radio Q Jogjakarta\"}, {\"id\":\"026058\",\"btr\":\"160\",\"cntr\":\"461E\",\"gnr\":\"8A7B\",\"nm\":\"88.3 The Dog\"}, {\"id\":\"0300D2\",\"btr\":\"55 64\",\"cntr\":\"461C\",\"gnr\":\"8A75\",\"nm\":\"88.3 The Wind\"}, {\"id\":\"0159E6\",\"btr\":\"128\",\"cntr\":\"4610\",\"gnr\":\"8A6C\",\"nm\":\"88.30 Z Fm Radio Word Online\"}]";

NSError *error = nil;
NSArray *stationArray = [NSJSONSerialization JSONObjectWithData:[example dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:&error];

if (!error)
{
    for (NSDictionary *stationDic in stationArray)
    {
        NSLog(@"\nName: %@ \nDump: \n%@", [stationDic valueForKey:@"nm"], stationDic);
    }
}
于 2013-02-08T12:30:34.053 に答える