尝试将大量数据加载到我的应用程序时,应用程序崩溃

3
我正在尝试将一个由40,000多条记录组成的JSON加载到我的Realm数据库中。这是我的函数:
AFJSONRequestOperation *operation = [[AFJSONRequestOperation alloc]init];
[AFJSONRequestOperation addAcceptableContentTypes:[NSSet setWithObject:@"text/html"]];

operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {

    NSArray *relations = [JSON copy];
    NSLog(@"COUNT SI %d",relations.count);

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSArray *relations = [JSON copy];
        RLMRealm *realm = [RLMRealm defaultRealm];
        [realm beginWriteTransaction];

        for (NSDictionary *dict in relations) {
            Relation *relation = [[Relation alloc]init];

            relation.rel_address = [NSString stringWithFormat:@"%@",[dict valueForKey:@"Address"]];
            relation.rel_balanceTotal = [[dict valueForKey:@"BalanceTotal"]doubleValue];
            relation.rel_bank_country_code = [NSString stringWithFormat:@"%@",[dict valueForKey:@"BankCountryCode"]];
            relation.rel_bank_number = [NSString stringWithFormat:@"%@",[dict valueForKey:@"BankNumber"]];
            relation.rel_city = [NSString stringWithFormat:@"%@",[dict valueForKey:@"City"]];
            relation.rel_city_id = [[dict valueForKey:@"CityId"]intValue];
            relation.rel_code = [NSString stringWithFormat:@"%@",[dict valueForKey:@"Code"]];
            relation.rel_country = [NSString stringWithFormat:@"%@",[dict valueForKey:@"Country"]];
            relation.rel_country_code = [NSString stringWithFormat:@"%@",[dict valueForKey:@"CountryCode"]];
            relation.rel_customerProspect = [NSString stringWithFormat:@"%@",[dict valueForKey:@"CustomerProspect"]];
            relation.rel_customerCode = [NSString stringWithFormat:@"%@",[dict valueForKey:@"CustomerProspectCode"]];
            relation.rel_email = [NSString stringWithFormat:@"%@",[dict valueForKey:@"Email"]];
            relation.rel_expired_total = [[dict valueForKey:@"ExpiredTotal"]doubleValue];
            relation.rel_fax = [NSString stringWithFormat:@"%@",[dict valueForKey:@"Fax"]];
            relation.rel_gsm = [NSString stringWithFormat:@"%@",[dict valueForKey:@"GSM"]];
            relation.rel_latitude = [[dict valueForKey:@"Latitude"]doubleValue];
            relation.rel_longitude = [[dict valueForKey:@"Longitude"]doubleValue];
            relation.rel_memo = [NSString stringWithFormat:@"%@",[dict valueForKey:@"Memo"]];
            relation.rel_name = [NSString stringWithFormat:@"%@",[dict valueForKey:@"Name"]];
            relation.rel_phone = [NSString stringWithFormat:@"%@",[dict valueForKey:@"Phone"]];
            relation.rel_turnovertotal = [[dict valueForKey:@"TurnoverTotal"]doubleValue];
            relation.rel_vat_country_code = [NSString stringWithFormat:@"%@",[dict valueForKey:@"VATCountryCode"]];
            relation.rel_vat_number = [NSString stringWithFormat:@"%@",[dict valueForKey:@"VATNumber"]];
            relation.rel_website = [NSString stringWithFormat:@"%@",[dict valueForKey:@"Website"]];
            relation.rel_zipcode = [NSString stringWithFormat:@"%@",[dict valueForKey:@"ZipCode"]];
            [realm addObject:relation];
        }
        [realm commitWriteTransaction];
        compblock(YES);

    });


} failure:^( NSURLRequest *request ,NSHTTPURLResponse *response ,NSError *error , id JSON ){
    NSLog(@"error is %@",error);
}];
[operation start];

当我处理1万个对象时,一切正常。但是当我处理4万个对象时,出现了以下错误:

Communications error: <OS_xpc_error: <error: 0x356dc614> { count = 1, contents =
    "XPCErrorDescription" => <string: 0x356dc86c> { length = 22, contents = "Connection interrupted" }
}>

有人能帮我吗?先谢谢了!!

编辑

在“COUNT SI”日志之前它崩溃了。所以我认为这与AFNetworking有关? 另外我注意到它在模拟器上没有崩溃...


3
哇哦——不要这样做。添加分页,使用CoreData。不要一次性加载这么多数据——这样是非常错误的。 - Grzegorz Krukowski
1
数据从哪里来?很可能,当您请求大量数据时,服务器花费了太多时间构建响应,导致连接超时。在类似的情况下,我不得不建立一种启发式方法来“调整”请求的大小,以防连接超时。 - Hot Licks
1
Grzegorz Krukowski 是正确的,你不应该一次性将这么多数据加载到内存中,但我认为没有理由使用 Core Data 而不是 Realm。事实上,一旦数据被插入,Realm 将使用更少的内存。JSON 解析是占用大量内存的原因。 - jpsim
嗨,Stef!你有解决方案吗?我遇到了同样的问题,但记录数量较少。 - Krunal
@Goti 目前我已经放弃使用 Core Data,转而使用 Realm (www.realm.io),速度快多了!!! - Steaphann
@StefGeelen 我也找到了解决方案,使用NSMutableString代替NSString。只需在NSMutableString对象中附加字符串即可清除我的障碍。顺便说一句,谢谢。 - Krunal
2个回答

7

这个问题与Realm无关。

我正在尝试加载超过40,000条记录的JSON

你的问题就在这里了。 AFJSONRequestOperation将尝试在内存中反序列化JSON,而您的应用程序将不再有任何可用内存,并会被终止。

我还注意到它没有在模拟器上崩溃...

这是因为模拟器比iOS设备具有更多的内存。

你应该找到减少网络请求大小的方法,可以通过一次请求较少数据或使用比JSON字符串更节约的响应格式来实现。


我现在要处理我的 JSON 中的分页!感谢你的帮助! - Steaphann

2

将循环体包裹在@autoreleasepool中。

同时复制相同的JSON两次似乎是冗余的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接