访问NSManagedObject的数据属性会给我带来内存问题

时间:2012-09-22 15:59:41

标签: iphone objective-c ios core-data nsfetchrequest

我想我可能会误解这个错误,也许有人可能会指出我正确的方向。

我有一个Entry实体,它与Media实体有一对多的关系。 Media实体包含名为originalImage的数据属性。

此迭代的前50个Entry实体在集合中没有任何media个项目。之后,它会在访问originalImage属性时变慢并最终耗尽内存并退出到主屏幕,除了NSLog中的先前内存警告之外没有任何消息。通过Instruments运行此操作还会显示此时内存不足。这是我的代码:

NSFetchRequest *oldFetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *oldEntryEntity = [NSEntityDescription entityForName:@"Entry"
                                                          inManagedObjectContext:oldMOC];
[oldFetchRequest setEntity:oldEntryEntity];
[oldFetchRequest setFetchBatchSize:10];
NSArray *entrys = [oldMOC executeFetchRequest:oldFetchRequest error:nil];

for (NSInteger index = 0; index < entrys.count; ++index) {

    Entry *entry = [entrys objectAtIndex:index];

    NSOrderedSet *oldMediaSet = [entry valueForKey:@"media"];

    for (Media *media in oldMediaSet) {

        @autorelease {

            [media valueForKey:@"originalImage"];    

        }

    }

}

删除originalImage行意味着它不会崩溃,这使我相信它与被访问的内容有关。也许我获得orderedSet的方式意味着这些项目留在内存中?

2 个答案:

答案 0 :(得分:1)

核心数据正在填充您正在访问的属性的故障,直到它填满了可用内存。你试图使用@autorelease来抵御这种情况,但这还不够,因为你没有得到一个自动释放的实例,而是对象图中的另一个对象。在不知道你想要做什么的情况下,很难说如何解决这个问题。你在循环中同步迭代直到内存不足,所以没有内存警告会中断这个过程。

答案 1 :(得分:0)

因此,如果您有一个循环尝试将数据从一个实体移动到另一个MOC中的新实体,那么您应该做的是获取旧实体,将数据分配给新实体(不要复制它) ,会使你的问题更糟糕),然后使用'refreshObject:mergeChanges:'来破坏旧对象和新对象。我相信这会有效,但我自己没有尝试过(假设有SQLite商店)。

核心数据编程指南“减少内存开销”中还有其他建议(pdf第148页)。