EXC_BAD_ACCESS with NSFetchedResultsController

2

Trying to track down this error I get when I have NSZombieEnabled.

I get an EXC_BAD_ACCESS when the fetched results controllers attempts to execute a fetch.

Debugger says:

-[CFNumber retain]: message sent to deallocated instance 0x6e88d10

Backtrace says:

#0  0x014bbe1e in ___forwarding___ ()
#1  0x014bbce2 in __forwarding_prep_0___ ()
#2  0x0145c490 in CFRetain ()
#3  0x0147929a in CFNumberCreate ()
#4  0x00b221ed in -[NSPlaceholderNumber initWithShort:] ()
#5  0x00b2216a in +[NSNumber numberWithShort:] ()
#6  0x010a549e in snapshot_get_value_as_object ()
#7  0x010a2a41 in _sharedIMPL_pvfk_core ()
#8  0x010a707d in -[NSManagedObject(_PFDynamicAccessorsAndPropertySupport)         _genericValueForKey:withIndex:flags:] ()
#9  0x010df6f0 in _PF_Handler_Public_GetProperty ()
#10 0x010df61d in -[NSManagedObject valueForKey:] ()
#11 0x00aea8d5 in -[NSObject(NSKeyValueCoding) valueForKeyPath:] ()
#12 0x00b1ad5e in _NSSortFunctionMany ()
#13 0x0152bf3f in __CFMergeSortArray_block_invoke_0 ()
#14 0x014b19d3 in __CFSimpleMergeSort ()
#15 0x014b1969 in __CFSimpleMergeSort ()
#16 0x014b1969 in __CFSimpleMergeSort ()
#17 0x014b1828 in CFSortIndexes ()
#18 0x014eb7e9 in CFMergeSortArray ()
#19 0x00b1828e in _sortedObjectsUsingDescriptors ()
#20 0x00b17fd9 in -[NSArray(NSKeyValueSorting) sortedArrayUsingDescriptors:] ()
#21 0x010853c6 in -[NSManagedObjectContext executeFetchRequest:error:] ()
#22 0x0118fc8f in -[NSFetchedResultsController performFetch:] ()
#23 0x000105c0 in -[RootViewController fetchedResultsController] (self=0x6d4bc80, _cmd=0x15a28) at /Users/david/Dropbox/Xcode/MyApp/MyApp/RootViewController.m:513
#24 0x0000e549 in -[RootViewController reloadTableView] (self=0x6d4bc80, _cmd=0x158d6) at /Users/david/Dropbox/Xcode/MyApp/MyApp/RootViewController.m:159
#25 0x01556ec9 in -[NSObject performSelector:withObject:withObject:] ()
#26 0x001dc5c2 in -[UIApplication sendAction:to:from:forEvent:] ()
#27 0x001dc55a in -[UIApplication sendAction:toTarget:fromSender:forEvent:] ()
#28 0x00281b76 in -[UIControl sendAction:to:forEvent:] ()
#29 0x0028203f in -[UIControl(Internal) _sendActionsForEvents:withEvent:] ()
#30 0x00281bab in -[UIControl sendActionsForControlEvents:] ()
#31 0x002cfa99 in -[UISegmentedControl _setSelectedSegmentIndex:notify:] ()
#32 0x002d1407 in -[UISegmentedControl touchesBegan:withEvent:] ()
#33 0x0020193f in -[UIWindow _sendTouchesForEvent:] ()
#34 0x00201c56 in -[UIWindow sendEvent:] ()
#35 0x001e8384 in -[UIApplication sendEvent:] ()
#36 0x001dbaa9 in _UIApplicationHandleEvent ()
#37 0x02442fa9 in PurpleEventCallback ()
#38 0x015291c5 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ ()
#39 0x0148e022 in __CFRunLoopDoSource1 ()
#40 0x0148c90a in __CFRunLoopRun ()
#41 0x0148bdb4 in CFRunLoopRunSpecific ()
#42 0x0148bccb in CFRunLoopRunInMode ()
#43 0x02441879 in GSEventRunModal ()
#44 0x0244193e in GSEventRun ()
#45 0x001d9a9b in UIApplicationMain ()
#46 0x000020ed in main (argc=1, argv=0xbffff5e8) at     /Users/david/Dropbox/Xcode/MyApp/MyApp/main.m:14

Here's the pertinent code in NSFetchedResultsController:

- (NSFetchedResultsController *)fetchedResultsController

{

    if (__fetchedResultsController != nil)
{
    return __fetchedResultsController;
}

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:kGestureEntity inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];

[fetchRequest setFetchBatchSize:0];

// sort keys
NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:kCategory ascending:YES];
NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc] initWithKey:kOrder ascending:YES]; // THIS IS AN INT 16 IN THE CORE DATA MODEL
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, sortDescriptor2, nil];

[fetchRequest setSortDescriptors:sortDescriptors];

//filter for males or females by tab index
//set the tabIndex so the fetchedResultsController knows which sex to filter
NSUInteger tabIndex = self.appDelegate.tabBarController.selectedIndex;
NSString *theSex = [NSString string];
if (tabIndex == 0)
    theSex = vFemale;
else
    theSex = vMale;

//determine if sitting or standing
NSInteger segmentIndex = self.segmentedControl.selectedSegmentIndex;
NSString *sittingOrStanding = [NSString string];
if (segmentIndex == 0)
    sittingOrStanding = vSitting;
else
    sittingOrStanding = vStanding;

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K like %@ AND (%K like %@ OR %K like %@)", kSex, theSex, kSittingOrStanding, sittingOrStanding, kSittingOrStanding, vBothSittingAndStanding];
[fetchRequest setPredicate:predicate];

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:kCategory cacheName:nil];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;

NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) //THIS IS WHERE EXC_BAD_ACCESS HAPPENS
    {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptor1 release];
[sortDescriptor2 release];
[sortDescriptors release];

return __fetchedResultsController;

}    

Only thing I can figure is the kOrder property in my core data model is set to an Int 16. But, I'm not sure what's prematurely releasing this CFNumber which appears to be retained via private methods. Any help is greatly appreciated.

Edit1: Header file:

@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;

Then in the implementation:

@synthesize fetchedResultsController=__fetchedResultsController;

Edit2: For clarity, my app worked fine with iOS 4 and only crashes with iOS 5.

iphone
ios
core-data
memory-management
nsfetchedresultscontroller
asked on Stack Overflow Oct 21, 2011 by David Nix • edited Oct 22, 2011 by David Nix

2 Answers

3

Set NSZombieEnabled, MallocStackLogging, and guard malloc in the debugger. Then, when your App crashes, type this in the gdb console:

(gdb) info malloc-history 0x6e88d10

Replace 0x6e88d10 with the address of the "message sent to deallocated instance" object that caused the crash, and you will get a much more useful stack trace and it should help you pinpoint the exact line in your code that is causing the problem.

See this article for more detailed instructions.

answered on Stack Overflow Oct 21, 2011 by chown
0

Are you actually retaining fetchedResultsController? In your header, do you use something similar to @property (nonatomic,retain) NSFetchedResultsController *fetchedResultsController; ? If not, then your FRC is being deallocated and the CFNumber is just the object that happens to be getting clobbered at the end of the responder chain.

answered on Stack Overflow Oct 21, 2011 by mattyohe

User contributions licensed under CC BY-SA 3.0