EXC_BAD_ACCESS和NSFetchedResultsController

试图追踪这个错误,当我有NSZombieEnabled

当获取的结果控制器尝试执行提取时,我得到一个EXC_BAD_ACCESS。

debugging器说:

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

Backtrace说:

 #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 

以下是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; } 

只有我kOrder是,我的核心数据模型中的kOrder属性被设置为一个Int 16。但是,我不确定什么是过早释放这个CFNumber ,似乎通过私有方法保留。 任何帮助是极大的赞赏。

编辑1:头文件:

 @property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController; 

然后在执行:

 @synthesize fetchedResultsController=__fetchedResultsController; 

编辑2:为了清楚起见,我的应用程序与iOS 4一起工作正常,只与iOS 5崩溃。

在debugging器中设置NSZombieEnabled , MallocStackLogging和guard malloc 。 然后,当你的应用程序崩溃时,在gdb控制台中input:

 (gdb) info malloc-history 0x6e88d10 

0x6e88d10replace为导致崩溃的"message sent to deallocated instance"对象的地址,您将得到一个更有用的堆栈跟踪,它应该可以帮助您确定导致问题的代码中的确切行。

有关更多详细说明,请参阅此文章。

你真的保留fetchedResultsController? 在你的头文件中,是否使用类似于@property(nonatomic,retain)的东西NSFetchedResultsController * fetchedResultsController; ? 如果没有,那么你的FRC被解除分配,而CFNumber只是在响应者链末端碰巧被破坏的对象。