在我的Garbage Collected Mac应用程序中,由于我将一个帮助函数放在一起以删除特定类型的所有Core Data实体,因此我的内存使用率非常高。这是函数,供参考:
- (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架构,因此无法设置类似级联删除规则的任何内容。无论如何,我在这里做错了什么?
答案 0 :(得分:0)
我遇到的解决此问题的最佳方法可能是重新设计我的数据模型,以创建一个中间对象,其中包含与我要删除的所有对象的多对多关系。通过将中间对象的删除规则设置为级联,可以删除中间对象并使其删除幕后剩余的对象。