3

我创建了一个使用核心数据的程序,它运行良好。

从那以后,我试图将我所有的核心数据方法调用和获取例程移动到一个自包含的类中。然后,我的主程序实例化该类并对该类进行一些基本的方法调用,然后该类在幕后处理所有核心数据。我遇到的是,有时我会发现当我从上下文中获取一个托管对象时,我将拥有一个有效的对象,但它的属性已被释放,我会导致崩溃。我玩过僵尸并寻找内存泄漏,我收集到的似乎是运行循环可能负责释放内存,但我不确定。

有没有办法确定该内存是否已被释放并在我需要访问它时强制核心数据取回它?我的 managedObjectContext 永远不会被释放,而 fetchedResultsController 也永远不会。

我想也许我需要使用 [managedObjectContext refreshObject:mergeData:] 方法或 [managedObjectContext setRetainsRegisteredObjects:] 方法。虽然,我的印象是最后一个可能不是最好的选择,因为它会占用更多的内存(据我所知)。

这些错误仅在我将核心数据调用移动到另一个类文件时才出现,并且它们出现时是随机的。

任何见解将不胜感激。

-瑞安

4

4 回答 4

1

我正在努力解决类似的问题。我正在使用托管对象类,并希望根据用户输入设置其属性。但是有时会释放属性,有时会释放整个托管对象。

在阅读了 Apple 文档http://developer.apple.com/library/IOs/#documentation/Cocoa/Conceptual/CoreData/Articles/cdMemory.html “托管对象上下文的作用”一章后,我了解到托管对象是释放每个运行循环完成。

并且有一个黄金建议

[myMangedObjectContext setRetainsRegisteredObjects:YES];

(我必须在我的视图控制器的 init 方法(对我来说是 initWithNibName)中设置它。)

您还应该考虑只保留您需要的对象,如文档中所述。但是自己读。

如果我不正确,请纠正我。

于 2011-11-14T12:39:59.230 回答
1

在我看来,您没有保留想要继续闲逛的物品。如果你正在做这样的事情:

NSArray *array = [moc executeFetchRequest:request error:&error];

您不拥有返回的数组,并且当当前自动释放池耗尽时,它很可能会消失。这将在运行循环完成处理当前事件时发生。

这一切都是猜测。如果你想要一个正确的答案,你需要发布你的代码。

于 2010-04-13T06:53:26.547 回答
1

根据您的描述很难知道问题出在哪里,但您可能需要查看Core Data 内存管理指南。您不必担心托管对象及其实体的内存管理(它们会自动获取和出错)。当您谈论“属性”时,您是指由 ivars 支持的自定义属性吗?如果是这样,这些应该是released indidTurnIntoFaultallocd 根据需要(可能在访问器中)。

于 2010-04-14T05:39:30.457 回答
0

我还创建了一个类来处理我所有的 CoreData 获取和东西。我遇到了几个问题,所以这里有一些提示。(如果我在这些示例中犯了任何内存管理错误,请告诉我。)

两件事情:


1) 在 CoreData 处理程序类中创建了一个“fetchFiredObject”方法。因此,当我想获得一个包含所有变量并且可以说是“全羽鸟”的 managedObject 时,而不是这样做:

aManagedObject *myManagedObject = [myCoreDataHandler.managedObjectStorageArray objectAtIndex:1];
int x = myManagedObject.someVariable.intValue;

相反,我这样做:

aManagedObject *myManagedObject = [myCoreDataHandler fetchFiredObjectAtIndex:1];
int x = myManagedObject.someVariable.intValue;

在 myCoreDataHandler 的 fetchFiredObjectAtIndex:i 方法中,我们进入数组,在索引 i 处找到对象键,然后对该对象键执行 fetchRequest,并返回新获取的 managedObject,这样它就不会出错或解除分配等:D


2)当我创建一个新的子视图控制器时,我会在创建时从父级填充它的“myCoreDataHandler”值。但是,这发生在创建新 viewController 的代码行之后的后续代码行上。因此,任何尝试使用 myCoreDataHandler 方法的子 viewDidLoad 代码都将返回空对象,因为 viewDidLoad在父代码的下一行代码之前完成,它在子对象中设置全局变量的值。因此,请确保您没有从 viewDidLoad 或 viewDidLoad 调用的任何本地方法中访问“核心数据处理对象”!而是在创建新的 viewController 后从父级调用它们。

于 2012-06-12T15:57:37.690 回答