views:

49

answers:

2

Hello,

I have a memory leak while using NSFetchedResultsController objectAtIndex: The stack frame is as follow:

   0 CoreFoundation __CFDataAllocate
   1 CoreFoundation __CFDataInit
   2 CoreData -[NSSQLCore _prepareResultsFromResultSet:usingFetchPlan:withMatchingRows:]
   3 CoreData -[NSSQLCore _newRowsForFetchPlan:selectedBy:withArgument:]
   4 CoreData -[NSSQLCore newRowsForFetchPlan:]
   5 CoreData -[NSSQLCore objectsForFetchRequest:inContext:]
   6 CoreData -[NSSQLCore executeRequest:withContext:error:]
   7 CoreData -[NSPersistentStoreCoordinator executeRequest:withContext:error:]
   8 CoreData -[NSManagedObjectContext executeFetchRequest:error:]
   9 CoreData _faultBatchAtIndex
  10 CoreData -[_PFBatchFaultingArray objectAtIndex:]
  --->  11 MyApp -[DocumentViewController tableView:heightForRowAtIndexPath:] 
  12 UIKit -[UISectionRowData refreshWithSection:tableView:tableViewRowData:]
  13 UIKit -[UITableViewRowData rectForFooterInSection:]
  14 UIKit -[UITableViewRowData heightForTable]
  15 UIKit -[UITableView(_UITableViewPrivate) _updateContentSize]
  16 UIKit -[UITableView noteNumberOfRowsChanged]
  17 UIKit -[UITableView reloadData]
  18 UIKit -[UITableView layoutSubviews]
  19 QuartzCore -[CALayer layoutSublayers]
  20 QuartzCore CALayerLayoutIfNeeded
  21 QuartzCore CA::Context::commit_transaction(CA::Transaction*)
  22 QuartzCore CA::Transaction::commit()
  23 QuartzCore CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*)
  24 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
  25 CoreFoundation __CFRunLoopDoObservers
  26 CoreFoundation __CFRunLoopRun
  27 CoreFoundation CFRunLoopRunSpecific
  28 CoreFoundation CFRunLoopRunInMode
  29 GraphicsServices GSEventRunModal
  30 GraphicsServices GSEventRun
  31 UIKit UIApplicationMain

From this stack frame, it looks like the object accessed with objectAtIndex get leaked.

However, when I leave the controller, its dealloc method get called. In this method, all the objects fetched by the fetchedresultscontroller are turned into fault since I use [NSManagedObjectContext refreshObject:mergeChange].

To be complete in my description, below is the code where the leaking object is created:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    Page* page = [[self fetchedResultsController] objectAtIndexPath:indexPath];
    UIImage* thumbnail = [page getThumbnail];
    [[self managedObjectContext] refreshObject:page.image mergeChanges:NO];
    CGFloat height = [PageCell cellImageSize:thumbnail].height + 20;
    return height;
}

Any hint would be appreciated, Thanks!

A: 

Barring more evidence, that looks more like a leak in the bowels of Core Data. File a bug.

bbum
So an interesting point: if I sent the "Low Memory Warning" to the simulator, the objects disappear. Would they be some kind of caching then?
Kamchatka
+1  A: 

Check the code where you get the UIImage. The leak is most likely there. Where it is exactly depends on how you create the image object.

TechZen