在 IOS(Objective-C)中有效地解析 JSON 到 Realm DB

Posted

技术标签:

【中文标题】在 IOS(Objective-C)中有效地解析 JSON 到 Realm DB【英文标题】:Parse JSON to Realm DB efficiently in IOS(Objective-C) 【发布时间】:2016-05-04 09:34:19 【问题描述】:

我是 Realm 和 Objective-C 的新手。我已经有一个应用程序可以读取 JSON 数组并解析为 Realm。工作正常,但需要 2:30 分钟来解析超过 20.000 个对象。我需要在更短的时间内完成解析。

这是我的 JSON 结构:

    "resultados":[
  
    "id": 1,
    "tipo": 9,
    "titulo": "name tittle curso",
    "id_padreactividad": 0,
    "hora": "16:55-20:30",
    "fecha": "15/02/2015",
    "acreditado": "Sí",
    "num_creditos": 0.5,
    "ubicacion": 2,
    "tema": "null",
    "patrocinadorId": 0
  ,
  
    "id": 2,
    "tipo": 16,
    "titulo": "Apertura e Introducción\n",
    "id_padreactividad": 1,
    "hora": "16:55-17:00",
    "fecha": "15/02/2015",
    "num_creditos": 0.0,
    "ubicacion": 2,
    "tema": "null",
    "patrocinadorId": 0,
    "descripcion": "null"
  ,ect...

这是我从 JSON 解析到领域的代码

//obtenemos los datos del json con esta simple estructura
    NSData *allCoursesData = [[NSData alloc] initWithContentsOfURL:
                              [NSURL URLWithString:@"String-for-http-direction-to-json"]];

    NSError *error;
    //hacemos el parseo del json, el error está creado por si fallara para que no siga
    NSMutableDictionary *allCourses = [NSJSONSerialization
                                       JSONObjectWithData:allCoursesData
                                       options:NSJSONReadingMutableContainers
                                       error:&error];

    if( error )
    
        NSLog(@"%@", [error localizedDescription]);
    
    else 
        NSArray *resultado = allCourses[@"resultados"];
        total=[resultado count];


        for ( NSDictionary *theCourse in resultado )
        
            // NSLog(@"Insertando actividad...%d",contador);
            NSLog(@"%d/%d",progress,total);
             contador=contador+1;


            Objeto=[[ActividadBean alloc] init];

            Objeto.id_act = [theCourse[@"id"] intValue];
            Objeto.tipo = [theCourse[@"tipo"]intValue];
            Objeto.titulo = theCourse[@"titulo"];
            Objeto.id_padreactividad = [theCourse[@"id_padreactividad"]intValue];
            Objeto.hora = theCourse[@"hora"];
            Objeto.fecha = theCourse[@"fecha"];
            Objeto.acreditado = theCourse[@"acreditado"];
            Objeto.num_creditos = [theCourse[@"num_creditos"] floatValue];
            Objeto.ubicacion = [theCourse[@"ubicacion"] intValue];
            Objeto.tema = theCourse[@"tema"];
            Objeto.patrocinadorId=[theCourse[@"patrocinadorId"]intValue];
            //guardamos el objeto
            [Objeto save];
        
    

这项工作正常,所有导入都没有问题,但需要一些时间(超过 20000 次解析需要 2:30 分钟)我知道 java 有方法“createAllFromJson”但我不知道 ios 是否有类似的东西。

【问题讨论】:

【参考方案1】:

您的代码的哪一部分仅用于构建allCourses 字典?目前尚不清楚您是从本地还是远程源获取 JSON,因此这可能会导致这个长度过程。

如果 JSON 反序列化需要大量时间,您可以考虑使用替代 JSON 解析器,或更高效的数据格式(如 Realm 或 BSON)。

在您的示例中还有一个对 [Objeto save] 的调用,我怀疑它会为 20.000 集合中的每个项目创建一个新的写入事务,这在 Realm 中有很大的开销。相反,您应该利用 Realm 的事务写入模型,并在单个写入事务中写入所有 20.000 个项目,这将加快 Realm 部分的速度。


我强烈建议您使用 Instruments.app 中包含的“时间分析器”来分析您的代码大部分时间花费在哪里。这将节省您将来的时间,而不是在 Stack Overflow 上让互联网上的陌生人猜测您的代码可能将时间花在哪里;)

【讨论】:

谢谢!你是对的,保存方法是问题所在,我为每个对象打开(并关闭)一个事务,一个写事务都可以正常工作!

以上是关于在 IOS(Objective-C)中有效地解析 JSON 到 Realm DB的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Objective-C iOS 中解析 JSON

使用 Objective-C 中的 Xcode 在 iOS 中以编程方式制作 UI 元素

IOS/Objective-C:按字符串中的单词数对 NSStrings 的 NSArray 进行排序

iOS JSON解析Objective-C并传递POST方法参数

如何在 iOS 上将“MongoDB 日期时间(ISO 日期)”解析为 NSDate(swift 和 Objective-c)

如何有效地迭代 NSSet (Objective-C) - Core Data 中的多对多关系表示?