EXC_BAD_ACCESS 与 NSFetchedResultsController
当我有 NSZombieEnabled 时,试图追踪这个错误。
当获取的结果控制器尝试执行获取时,我收到 EXC_BAD_ACCESS。
调试器说:
-[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
属性设置为 Int 16。但是,我不确定什么是过早的释放这个似乎是通过私有方法保留的CFNumber
。非常感谢任何帮助。
Edit1:头文件:
@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
然后在实现中:
@synthesize fetchedResultsController=__fetchedResultsController;
Edit2:为了清楚起见,我的应用程序在 iOS 4 上运行良好,仅在 iOS 5 上崩溃。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
设置 NSZombieEnabled,MallocStackLogging 和 在调试器中保护 malloc。然后,当您的应用崩溃时,在 gdb 控制台中输入以下内容:
将
0x6e88d10
替换为导致崩溃的“消息发送到已释放实例”
对象的地址,然后您将获得更有用的堆栈跟踪,它应该可以帮助您查明代码中导致问题的确切行。请参阅本文以获取更详细的说明。
Set NSZombieEnabled, MallocStackLogging, and guard malloc in the debugger. Then, when your App crashes, type this in the gdb console:
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.