2013-01-19 72 views
1

在我的应用程序中,我使用核心数据来存储信息。当应用程序最初推出这个代码块被调用来获取数据:核心数据内存分配

NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription entityForName: @"Customer" inManagedObjectContext: managedObjectContext]; 
request.entity = entity; 

NSError *error = nil; 

Array = [[managedObjectContext executeFetchRequest: request error: &error] mutableCopy]; 
NSArray * reversedArray = [[Array reverseObjectEnumerator] allObjects]; 
[Array release]; 
Array = nil; 
[request release]; 
[error release]; 

所以一切正常,但存在分配不获取发布了非常大量的内存,我似乎无法弄明白。你可以通过下面的截图看到。任何帮助都会很棒。

enter image description here

enter image description here

编辑

我最初接受下面的答案,但它似乎并没有摆脱问题了100%。 CFData(商店)仍然分配了很多没有被释放的内存。这最终导致了iPad 2上的崩溃,当我接受下面的答案时我没有遇到过,因为我只是在iPad 4上进行测试。我希望这会清除所有内容。

EDIT 2

所以我一直在做更多的测试和调试,似乎被添加到核心数据的多个条目越大CFData(存储)越来越。目前,数据库中只有10个单独的条目,并且在打开应用程序时从中获取的分配超过25MB。主要实体“客户”与其他更大的实体有多重关系。所以当我执行“客户”的提取时,与它有关系的每个实体都被取出,这导致了巨大的内存分配。有没有办法解决这个问题?

我猜想必须有更好的方法来设置如何添加条目以及如何获取条目。

这里是如何创建一个条目代码:

- (void) addItem 
{ 
// Insert a new record in the database 
Customer * customerItem = [NSEntityDescription insertNewObjectForEntityForName: @"Customer" inManagedObjectContext: managedObjectContext]; 

System * system = [NSEntityDescription insertNewObjectForEntityForName: @"System" inManagedObjectContext: managedObjectContext]; 

Form1 * form1 = [NSEntityDescription insertNewObjectForEntityForName: @"Form1" inManagedObjectContext: managedObjectContext]; 

Form2 * form2 = [NSEntityDescription insertNewObjectForEntityForName: @"Form2" inManagedObjectContext: managedObjectContext]; 

Form3 * form3 = [NSEntityDescription insertNewObjectForEntityForName: @"Form3" inManagedObjectContext: managedObjectContext]; 

Form4 * form4 = [NSEntityDescription insertNewObjectForEntityForName: @"Form4" inManagedObjectContext: managedObjectContext]; 

Form6 * form6 = [NSEntityDescription insertNewObjectForEntityForName: @"Form6" inManagedObjectContext: managedObjectContext]; 

Form7 * form7 = [NSEntityDescription insertNewObjectForEntityForName: @"Form7" inManagedObjectContext: managedObjectContext]; 

Form8 * form8 = [NSEntityDescription insertNewObjectForEntityForName: @"Form8" inManagedObjectContext: managedObjectContext]; 

Form9 * form9 = [NSEntityDescription insertNewObjectForEntityForName: @"Form9" inManagedObjectContext: managedObjectContext]; 

Form10 * form10 = [NSEntityDescription insertNewObjectForEntityForName: @"Form10" inManagedObjectContext: managedObjectContext]; 

Form11 * form11 = [NSEntityDescription insertNewObjectForEntityForName: @"Form11" inManagedObjectContext: managedObjectContext]; 

customerItem.system = system; 
customerItem.form1 = form1; 
customerItem.form2 = form2; 
customerItem.form3 = form3; 
customerItem.form4 = form4; 
customerItem.form6 = form6; 
customerItem.form7 = form7; 
customerItem.form8 = form8; 
customerItem.form9 = form9; 
customerItem.form10 = form10; 
customerItem.form11 = form11; 

// Insert a new item in the table's data source 
[customerArray insertObject: customerItem atIndex: 0]; 

[managedObjectContext save: &error]; 

// Insert a new row in the table 
NSIndexPath *indexPath = [NSIndexPath indexPathForRow: 0 inSection: 0]; 
[table insertRowsAtIndexPaths: [NSArray arrayWithObject: indexPath] withRowAnimation: UITableViewRowAnimationFade]; 
} 
+0

上述代码完成后'reversedArray'会发生什么?它坚持所有提取的对象,但是你没有指出它会发生什么。只要它继续存在,获取的对象也是如此。 –

+0

我将我的代码更新为下面的答案,所以reversedArray正在自动发布 – Sean

+0

@ ipmcc的答案有多大的区别?你说这不是100%,那么多少? 1%? 50%? 99%? –

回答

1

核心数据都将有它需要以执行其功能的长寿命的记忆一定量。这就是说,你可以额外确保你已经通过在@autorelease池包装这个代码在这里尽量减少内存使用,就像这样:

@autoreleasepool { 
    NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName: @"Customer" inManagedObjectContext: managedObjectContext]; 
    request.entity = entity; 

    NSError *error = nil; 

    Array = [[managedObjectContext executeFetchRequest: request error: &error] mutableCopy]; 
    NSArray * reversedArray = [[[Array reverseObjectEnumerator] allObjects] retain]; 
    [Array release]; 
    Array = nil; 
    [request release]; 
    [error release]; 
} 
[reversedArray autorelease]; 

即使你一直小心地释放所有你创建的对象时,自动释放模式在整个系统框架中被广泛使用。

请注意,在添加此@autoreleasepool后,您需要保留reversedArray以使其持续通过池的范围退出。之后我添加了[reversedArray autorelease],所以代码在语义上与您发布的代码相同(除了释放执行获取请求所创建的任何自动发布的对象之外)。