当与动态Tableview高度一起使用时,核心数据消耗大量内存

时间:2012-07-17 18:12:47

标签: objective-c ios core-data memory-management nsfetchedresultscontroller

我的核心数据在iphone上消耗了大量内存。在开始时,我按如下方式设置了一个fetchrequest:

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Tweets" inManagedObjectContext: [[ChubbyEyetwitterEngine sharedInstance] getManagedObjectContextForUse]]; 

NSPredicate *predicate =[NSPredicate predicateWithFormat:@"isWatchList==NO && favorited == NO  && accountHolder.id_str == %@ ",[[ChubbyEyetwitterEngine sharedInstance] getActiveUserID]];

// Define how we will sort the records
NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:[sortTweetaryTimeLine objectForKey:@"sortKey"] ascending:[[sortTweetaryTimeLine objectForKey:@"ascending"] boolValue]] autorelease];   

NSSortDescriptor *secondarySortKey = [[[NSSortDescriptor alloc] initWithKey:@"created_at" ascending:FALSE] autorelease]; 


NSArray *sortDescriptors = [NSArray arrayWithObjects:
                            sortDescriptor,
                            secondarySortKey,nil];

NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entity];
[request setPredicate:predicate];
[request setSortDescriptors:sortDescriptors];


if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) 
{
    //smaller batch on iphone
    [request setFetchBatchSize:12];

}else {
    //bigger on the ipad
    [request setFetchBatchSize:100];

}

//prefetching important relationships to cache data
[request setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObjects:@"ownerOfThisTweetary",@"thisEntity", nil]];


diaryFetchResultsController= [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:[[ChubbyEyetwitterEngine sharedInstance] getManagedObjectContextForUse] sectionNameKeyPath:[sortTweetaryTimeLine objectForKey:@"sectionName"] cacheName:nil] ;   




NSError *fetchError = nil;
if ([diaryFetchResultsController performFetch:&fetchError]) {

}else
{

}

diaryFetchResultsController.delegate = self;

在此之后我在我的tabeview上调用reloadData。在我的tableview中,我根据text属性的长度以及我的managedobject上的其他属性动态计算单元格的高度,并返回高度。

这里的问题是,在调用重载数据时,fetchedresultscontroller中的所有对象都调用了heightforrow,这反过来会将对象故障排入内存。现在我的tableview有很多对象,进入数百个,我的内存消耗量增加了。

我正在寻找一种节省内存的方法:

我尝试过做什么:     [diaryFetchResultsController.managedObjectContext setStalenessInterval:2.0]; 这没有任何影响,或者至少是我能看到的效果,所以我尝试了别的东西 - >

在heightForRowAtIndexPath中,在我计算高度后,我试过[diaryFetchResultsController.managedObjectContext refreshObject:object mergeChanges:YES]; 结果很糟糕,并导致无限循环,实际发生的是当对象出现故障时,系统会自动为该索引路径调用heightForRowAtIndexPath。

我的第二次尝试是从heightForRowAtIndexPath中删除刷新对象,而是插入我的cellForRowAtIndexPath的末尾。与上述结果相同。

我的第三次尝试::

- (void)turnMeBackIntoAfault {

  for (id object in diaryFetchResultsController.fetchedObjects){

    [diaryFetchResultsController.managedObjectContext refreshObject:object mergeChanges:YES];
 }

}

然后我在tableview上调用reloadData后立即调用此方法。结果是对所有单元格调用了一次heightForRowAtIndexPath(如预期的那样),然后在所有manageobjects上调用turnMeBackIntoAfault。然而,坏消息是在系统再次调用所有单元格的heightForRowAtIndexPath之后,因此否定了将对象转换回故障的影响。 我也试过设置tableveiw代表&数据源为nil& fetchedresultscontroller在发生故障之前委托给nil并在循环后将它们重新设置为self,但效果仍然相同。

现在我绝对相信它的heightForRowAtIndexPath导致大量内存消耗。我已尝试将heightForRowAtIndexPath注释掉,并且我的可用内存几乎超过1.5倍。

拥有动态行对我的应用程序至关重要,并且即使我的应用程序广泛使用fetchedresultControllers和tableviews,我也会遇到内存不足的情况。

任何帮助节省内存将不胜感激!我一整天都在摸不着头脑。

0 个答案:

没有答案