【问题标题】:High memory usage on Core Data deleteCore Data 删除时内存使用率高
【发布时间】:2011-09-17 03:47:54
【问题描述】:

在我的 Garbage Collected Mac 应用程序中,由于我使用了一个帮助函数来删除特定类型的所有核心数据实体,我的内存使用率非常高。函数如下,供参考:

- (void)deleteAllObjectsForEntity:(NSString *)entityDescription {
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:entityDescription inManagedObjectContext:self];
    [request setEntity:entity];
    [request setIncludesPropertyValues:NO];

    NSError *error = nil;
    NSArray *items = [self executeFetchRequest:request error:&error];
    [request release];

    // Delete all objects
    for (NSManagedObject *managedObject in items) 
    {
        [self deleteObject:managedObject];
    }

    // Should probably check for errors here
    [self save:&error];
    [self reset];

    // Suggest the garbage collector tries to tie up any loose ends
    [[NSGarbageCollector defaultCollector] collectIfNeeded];
}

通过使用堆分析,我可以看到每次使用上述函数删除我的 FileRecord 实体的所有实例时,堆都会增长大约 50MB。似乎永远无法恢复的记忆。

通过使用-com.apple.CoreData.SQLDebug 1 启动参数,我可以看到大部分内存是由我的NSFetchRequest 期间触发的(许多)SELECT 语句引起的。似乎每次选择这些对象时,Core Data 都会触发错误(并因此分配内存)。显然我不需要触发这些错误,因为我随后将删除该对象。这是我的控制台输出示例:

CoreData: annotation: fault fulfilled from database for : 0x2002ed3e0 <x-coredata://17E6216A-C2FA-42A6-B8E4-5209CD1AB2CA/FileRecord/p117418>

CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNORMALIZEDPATH, t0.ZSIZE, t0.ZFILENAME, t0.ZKIND, t0.ZNORMALIZEDFILENAME, t0.ZPATH FROM ZFILERECORD t0 WHERE  t0.Z_PK = ?

无论我做什么,我都无法让这段记忆被放弃。如您所见,我保存然后重置我的 NSManagedObjectContext。此外,我向垃圾收集器暗示它可能会尝试收集任何滞留数据。

不幸的是,我正在使用现有的 Core Data 架构,因此无法设置诸如级联删除规则之类的任何内容。无论如何,我在这里做错了什么?

【问题讨论】:

  • 为什么要继承 NSManagedObjectContext?
  • 我没有继承 NSManagedObjectContext。我的 deleteAllObjectsForEntity 方法存在于一个类别中。
  • 好吧,哈哈,我建议运行垃圾收集器工具,看看收集器在此操作期间实际尝试做什么。
  • 您通常在此循环中删除多少对象?
  • @ndg 我知道这已经很久了,但是您找到解决方案了吗?我已经为此头疼了好几天。堆增加,如果我重复执行一段时间,我的应用程序会因内存警告而被杀死。

标签: cocoa core-data garbage-collection nsmanagedobject


【解决方案1】:

也许解决我遇到的这个问题的最佳方法是重新设计我的数据模型以创建一个中间对象,该对象包含与我要删除的所有对象的一对多关系。通过将中间对象的删除规则设置为级联,可以删除中间对象并让它在后台删除剩余的对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-28
    • 2013-08-26
    • 1970-01-01
    • 2010-11-11
    • 2014-08-13
    • 1970-01-01
    • 2012-08-30
    • 1970-01-01
    相关资源
    最近更新 更多