这是我通过乐器运行应用程序时得到的结果。它正在处理大量核心数据。我可以看到这显然是不对的,但我真的不知道这个截图告诉我的是什么。似乎是什么问题?如果您感兴趣,那么缩小的代码就是:
NSFetchRequest *oldFetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *oldEntryEntity = [NSEntityDescription entityForName:@"Entry"
inManagedObjectContext:oldContext];
[oldFetchRequest setEntity:oldEntryEntity];
int numberOfEntries = [oldContext countForFetchRequest:oldFetchRequest error:nil];
int batchSize = 4;
[oldFetchRequest setFetchLimit:batchSize];
int offset = 0;
while (numberOfEntries - offset > 0) {
@autoreleasepool {
[oldFetchRequest setFetchOffset:offset];
NSError *error;
NSArray *entries = [oldContext executeFetchRequest:oldFetchRequest error:&error];
for (NSManagedObject *entry in entries) {
@autoreleasepool {
Entry *newEntry = [NSEntityDescription insertNewObjectForEntityForName:@"Entry"
inManagedObjectContext:newContext];
newEntry.entryID = [entry valueForKey:@"entryID"];
NSMutableOrderedSet *newMediaSet = [[NSMutableOrderedSet alloc] init];
NSOrderedSet *mediaSet = [entry valueForKey:@"media"];
int i = 0;
for (NSManagedObject *media in mediaSet) {
Media *newMedia = [NSEntityDescription insertNewObjectForEntityForName:@"Media"
inManagedObjectContext:newContext];
newMedia.isInPhotoLibrary = [media valueForKey:@"isInPhotoLibrary"];
newMedia.positionInEntry = [NSNumber numberWithDouble:i + 1];
MediaImageData *imageData = [NSEntityDescription insertNewObjectForEntityForName:@"MediaImageData"
inManagedObjectContext:newContext];
imageData.data = [media valueForKey:@"originalImage"];
newMedia.imageData = imageData;
newMedia.entry = newEntry;
[newMediaSet addObject:newMedia];
i++;
}
newEntry.media = newMediaSet;
}
}
[newContext save:&error];
offset = offset + batchSize;
}
}
编辑:我按照这里给出的建议,将它包装在@autoreleasepools(我已在上面编辑过)中,并且在发生这种情况后它仍然崩溃:
它显然比第一次进入代码,但它仍然崩溃。
答案 0 :(得分:2)
不讨论代码的效率:
将您的代码包含在@autoreleasepool {}
中,用于外部(while)和内部(for)循环
否则,你只需要分配大量内存并在外部事件循环到达循环结束时释放它。
答案 1 :(得分:1)
尝试在for
中包装快速枚举(@autoreleasepool
循环)的内部,这应该会有所帮助。当更改达到危险的内存消耗时,您还可以运行某种计数器来保存环路中的上下文。
你确实有很多对象,考虑优化数据结构。
答案 2 :(得分:1)
首先,就发布核心数据相关问题提出一些建议。几乎没有太多信息。当您省略细节时,人们很难帮助您,因为有太多可能的互动。
只要查看您发布的代码,就会留下太多问题。
我希望看到按整体大小排序的信息,而不是分配数量。这将更容易告诉你内存的使用位置。事实上,我无法看到那张照片中的内存使用位置(然后再次 - 老眼睛 - 当我放大它时,它会变得太模糊)。
如果您认为它与核心数据有关,为什么不运行核心数据工具?
接受一些诊断帮助。
您的新MOC是直接连接到PSC还是拥有父MOC?如果它有父MOC,则保存只会被推送到父MOC中,并且将保留在内存中,直到保存持久存储到数据库。
您的mediaSet中有多少项?它可能有很多可能会扼杀记忆的东西。
您将哪些参数应用于FetchRequest和MOC?根据这些选项,MOC可以保留对象。检查这一点的方法是记录每个MOC的保留/插入/删除/等设置的计数。通过记录这些,您可以看到MOC是否持有您认为不应该存在的东西。
然后您就可以知道是否需要刷新/重置MOC。
你可以作弊,并在保存后调用[moc reset]
,但是在这之前/之后看到数字会很好,这样你就可以说服自己记忆的位置。
做更多调试。给自己更多的信息,这样你就可以做出正确的决定......它也会为我们提供更好的信息来帮助你。
修改强>
Oooops。我删除了关于可能没有太多内存的评论。我的老眼睛没有看到那张图片上的小字体。
修改强>
感谢。如何记录保留/插入/删除的集的计数 对于每个MOC? - 安德鲁
MOC有几个属性(registeredObjects
,insertedObjects
,deletedObjects
,updatedObjects
),提供一组与这些类别匹配的对象。只需NSLog
每个类别中对象的数量。对于每个MOC,您可以看到MOC随时间跟踪的对象数量。
此外,启用核心数据工具。它们确实非常有用。