【问题标题】:Core Data Performance issue in device设备中的核心数据性能问题
【发布时间】:2012-05-16 05:17:56
【问题描述】:

我的应用程序需要使用 Web 服务并以 json 格式获取一些数据。 我需要解析 json 并在我的持久性存储中提供数据,一切都运行良好,直到我在实际设备中测试我的应用程序,应用程序看起来就像它一直持有它,直到我感到沮丧,然后最后它在我的脸上拉屎 x -(

这里我有一个 insertOrReplaceObjectForEntityForName 的方法

+(id) insertOrReplaceObjectForEntityForName:(NSString *)entityName inManagedObjectContext:_context WithPredicateString:(NSString *)predicateString, ...{

    NSManagedObject *object;

    va_list ap;
    va_start(ap, predicateString);

    NSFetchRequest *req = [[NSFetchRequest alloc] initWithEntityName:entityName];
    NSPredicate *pred = [NSPredicate predicateWithFormat:predicateString arguments:ap];
    [req setPredicate:pred];

    int count = [_context countForFetchRequest:req error:nil];

    if(count > 0){
        NSArray *arr = [_context executeFetchRequest:req error:nil];
        object = [arr objectAtIndex:0];
    }
    else{
        object = [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:_context];
    }

    va_end(ap);

    return object;
}

在这里,一行的简单操作大约需要 0.004 秒,在解析数据时,我必须结合许多其他操作执行大约 1000 次此操作,这使得我的解析过程过于繁重。我的默认数据库中已经有很多药物,我必须检查药物是否存在,如果存在,我必须编辑它的值。

Drug *drug = [NSEntityDescription insertOrReplaceObjectForEntityForName:@"Drug" inManagedObjectContext:parsingContext WithPredicateString:[NSString stringWithFormat:@"drugId == '%@'",[drugDetails objectForKey:@"DrugId"]]];

我使用核心数据来保持应用程序中的历史记录,但现在我认为我需要远离核心数据并忘记保留历史记录,除非这里有人可以帮助我。 我已经花了很多时间来制作我的应用程序,现在客户正在打我的腿,有什么建议吗??

【问题讨论】:

  • 1000 对于核心数据来说已经很多了。尝试跳过计数。如果[_context executeFetchRequest:req error:nil]; 返回 0 个对象,则不需要计数操作。另一种操作是一次捆绑 20 个 drugID,以减少获取次数。最后,确保所有这些都发生在后台队列中。
  • 我已经处理了后台队列等问题。但问题是提取需要很多时间,并且性能会降低很多倍。
  • 你认为一次获取​​所有记录并使用filteredArrayUsingPredicate方法会更快吗?
  • 几乎可以肯定。虽然有 1000 条记录,但请注意内存使用情况。可以小批量进行(例如一次 50 或 100 个),具体取决于您的内存使用量。

标签: iphone performance core-data ios-simulator device


【解决方案1】:

瑜伽,

您看到的延迟并不是特别来自 Core Data,而是来自 iOS 设备上闪存的缓慢速度。您如何缓解这种情况?

Flash 读取非常大的块(我被告知 128kB),然后必须在 DB scatter-gather 操作中将它们丢弃。因此,您希望从每次获取中获取尽可能多的数据。

您的代码会提取 json 中的每个项目。如果您使用 Instruments 的低级工具,就像我在我的应用程序中使用的那样,您很可能会看到您的应用程序大部分时间都处于空闲状态,等待闪存。

您使用in 谓词运算符构建聚合提取。 IOW,去收集你所有的drugIDs 到一个集合或数组中。顺便说一句,根据您的 json,这通常可以通过使用 -valueForKey: 的单行代码来完成。就像这种谓词格式:

@"drugId in'%@'", [drugDetails valueForKey:@"DrugId"]

其中drugDetails 是一个对象数组。此搜索让数据库聚合其所有页面获取。然后它会返回一个已经存在的记录数组。然后,您可以轻松地使用集合操作来根据需要选择更新或创建记录。然后您可以将它们刷新到单个-save: 中。

安德鲁

【讨论】:

  • 谢谢 Adonoho,这真的很有帮助。顺便问一下,IOW和BTW是什么意思?
  • Yogesh, IOW == 换句话说;顺便说一句 == 顺便说一句。顺便说一句,谓词格式中有一些不需要的字符:@"drugId in %@", [drugDetails valueForKey:@"DrugId"]。另外,如果您认为我的回答对您最有用,请检查向上/向下箭头的复选标记。安德鲁
  • 我没有这个权利,没有足够的分数来评价你,如果你给我的 qn +1 那么我可能会投票给你
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-20
  • 2011-07-03
相关资源
最近更新 更多