最初,我的应用程序崩溃了BAD_EXEC_ACCESS。我打开了NSZombieEnabled,输出如下。崩溃是非常不一致的,如果它崩溃,它总是在三个地方之一崩溃,但它在经过那些代码行时并不总是崩溃。即有时它会在前10个用户交互中的其中一个地方崩溃,有时候我可以持续按下控件(通过这些代码行)超过一分钟,然后它最终崩溃。
NSZombieEnabled的输出也不一致,如“崩溃位置#2”中所述 - 两个NSZombieEnabled输出是应用程序在同一行代码上崩溃但具有不同NSZombieEnabled输出的示例。
我知道通常这种类型的错误意味着我过度释放某些东西,但我不能弄清楚我做错了什么。
我遵循的内存管理规则是:
(我听说“将IBOutlets设置为nil”与内存管理有关,但我没有找到关于如何完成此操作的充分描述,因此我的应用程序中没有这样做。)
如果我能提供任何有用的其他信息,请告诉我。
提前致谢!对不起,如果我太长而且彻底(INTP)!
-Roben
以下是崩溃输出的一些记录。发生崩溃时,它始终位于这三个位置之一。通过在崩溃后进行回溯并查找我编写的行号和代码文件来确定位置。
崩溃位置#1:
if (![[self fetchedResultsController] performFetch:&error])
示例崩溃位置#1 NSZombieEnabled输出:
*** -[Not A Type release]: message sent to deallocated instance 0x3b3f570
崩溃地点#2:
NSMutableArray *tips = [NSMutableArray arrayWithArray: [[[categories objectAtIndex: indexPath.row] valueForKey:@"tips"] allObjects]];
示例崩溃位置#2 NSZombieEnabled输出:
*** -[CFArray retain]: message sent to deallocated instance 0x3e53990
*** -[NSFetchRequest retain]: message sent to deallocated instance 0x3b2f2c0
崩溃地点#3:
NSMutableArray *tips = [NSMutableArray arrayWithArray: [[[justOneCategory objectAtIndex: 0] valueForKey:@"tips"] allObjects]];
示例崩溃位置#3 NSZombieEnabled输出:
*** -[UIViewControllerWrapperView retain]: message sent to deallocated instance 0x3e593a0
示例Backtrace(这对应于第3行):
#0 0x01d6a3a7 in ___forwarding___ ()
#1 0x01d466c2 in __forwarding_prep_0___ ()
#2 0x01cfd988 in CFRetain ()
#3 0x01cfd495 in CFArrayCreate ()
#4 0x01d406c3 in -[__NSPlaceholderArray initWithObjects:count:] ()
#5 0x01d5d34a in +[NSArray arrayWithObjects:count:] ()
#6 0x01d6386e in -[NSSet allObjects] ()
#7 0x00003bbc in -[RootViewController getRandomTip:] (self=0x3b24ea0, _cmd=0x7447, sender=0x3b38330) at /Users/***/Classes/RootViewController.m:36
#8 0x00299405 in -[UIApplication sendAction:to:from:forEvent:] ()
#9 0x002fcb4e in -[UIControl sendAction:to:forEvent:] ()
#10 0x002fed6f in -[UIControl(Internal) _sendActionsForEvents:withEvent:] ()
#11 0x002fdabb in -[UIControl touchesEnded:withEvent:] ()
#12 0x002b2ddf in -[UIWindow _sendTouchesForEvent:] ()
#13 0x0029c7c8 in -[UIApplication sendEvent:] ()
#14 0x002a3061 in _UIApplicationHandleEvent ()
#15 0x0252ed59 in PurpleEventCallback ()
#16 0x01d41b80 in CFRunLoopRunSpecific ()
#17 0x01d40c48 in CFRunLoopRunInMode ()
#18 0x0252d615 in GSEventRunModal ()
#19 0x0252d6da in GSEventRun ()
#20 0x002a3faf in UIApplicationMain ()
#21 0x00002a60 in main (argc=1, argv=0xbfffef9c) at /Users/***/main.m:14
编辑:添加Griffo要求的其他一些代码和输出
感谢您的回复,更多具体的代码可以提供哪些帮助?现在,这里包含崩溃位置#1和崩溃位置#2的整个方法。
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == ALLTIPS_SECTION) {
self.tipsController.title = @"Tips";
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
// NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
// abort();
}
self.tipsController.tips = [NSArray arrayWithArray: [fetchedResultsController fetchedObjects]];
} else {
self.tipsController.title = [[categories objectAtIndex: indexPath.row] name];
NSMutableArray *tips = [NSMutableArray arrayWithArray: [[[categories objectAtIndex: indexPath.row] valueForKey:@"tips"] allObjects]];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending: YES];
[tips sortUsingDescriptors: [NSArray arrayWithObject: sortDescriptor]];
[sortDescriptor release];
self.tipsController.tips = [NSArray arrayWithArray: tips];
}
[self.navigationController pushViewController:self.tipsController animated:YES];
}
我没有针对您询问的具体崩溃运行malloc_history,但是我确实在#3上运行了它,这里输出,我不知道我应该如何解析这个,所以任何建议都会有所帮助(在所有关于malloc_history的教程我已经阅读了它们显示的输出,它们都像“它就在那里”而我就像“在哪里?wtf你在看”:)
ALLOC 0x3b55130-0x3b5516f [size=64]: thread_a0a3f500 |start | main | UIApplicationMain | GSEventRun | GSEventRunModal | CFRunLoopRunInMode | CFRunLoopRunSpecific | PurpleEventCallback | _UIApplicationHandleEvent | -[UIApplication sendEvent:] | -[UIWindow _sendTouchesForEvent:] | -[UIControl touchesEnded:withEvent:] | -[UIControl(Internal) _sendActionsForEvents:withEvent:] | -[UIControl sendAction:to:forEvent:] | -[UIApplication sendAction:to:from:forEvent:] | -[RootViewController getRandomTip:] | -[_NSFaultingMutableSet allObjects] | -[_NSFaultingMutableSet willRead] | -[NSManagedObjectContext(_NSInternalAdditions) _retainedObjectWithID:optionalHandler:withInlineStorage:] | +[NSManagedObject(_PFDynamicAccessorsAndPropertySupport) allocWithEntity:] | _PFAllocateObject | malloc_zone_calloc
----
FREE 0x3b55130-0x3b5516f [size=64]: thread_a0a3f500 |start | main | UIApplicationMain | GSEventRun | GSEventRunModal | CFRunLoopRunInMode | CFRunLoopRunSpecific | __CFRunLoopDoObservers | _performRunLoopAction | -[_PFManagedObjectReferenceQueue _processReferenceQueue:] | _PFDeallocateObject | malloc_zone_free
ALLOC 0x3b55130-0x3b55153 [size=36]: thread_a0a3f500 |start | main | UIApplicationMain | GSEventRun | GSEventRunModal | CFRunLoopRunInMode | CFRunLoopRunSpecific | __CFRunLoopDoObservers | CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) | CA::Transaction::commit() | CA::Context::commit_transaction(CA::Transaction*) | CALayerLayoutIfNeeded | -[CALayer layoutSublayers] | -[UILayoutContainerView layoutSubviews] | -[UINavigationController _startDeferredTransitionIfNeeded] | -[UINavigationController _startTransition:fromViewController:toViewController:] | +[UIViewControllerWrapperView wrapperViewForView:frame:] | +[NSObject alloc] | +[NSObject allocWithZone:] | _internal_class_createInstance | _internal_class_createInstanceFromZone | calloc | malloc_zone_calloc
答案 0 :(得分:3)
有几点需要注意:
首先,关于“设置为零”,这是一个很好的做法。无论何时释放某些东西,立即将其设置为零。这意味着-dealloc通常看起来像这样(或者其他十几种带有分号,两行等的样式):
[_foo release], _foo = nil;
但我怀疑这是你的问题。在您发送的malloc_history中,它显示有问题的对象是NSManagedObject,因此它是Core Data之外的东西。确保您已阅读Memory Management Using Core Data文档。
如果您有10.6,那么我强烈推荐使用静态分析仪。点击Cmd-Shift-A,它会寻找明显的内存错误。我发现它非常好。
答案 1 :(得分:0)
可能是由于您自动释放后来引用的对象,这可能解释了不一致性
“非类型”发布错误可能取决于您在代码中发布未定义为“某事”的内容。您是否为“非类型”错误引用的解除分配的实例运行“shell malloc history”命令?
需要真正看到更多代码...
答案 2 :(得分:0)
这就是发生崩溃的地方,但这并不意味着它就是bug的所在。发生崩溃是因为释放的对象正在发送消息,但该错误可能是当您仍想使用该对象时首先取消分配该对象的事实。我有一种模糊的感觉,最初取消分配的对象可能是tipsController
或fetchedResultsController
,而且它也会发布其他内容。
答案 3 :(得分:0)
我有这个错误。我复制并粘贴了另一个应用程序的代码,其工作方式略有不同。就我而言,我在viewDidUnload&中释放变量。 viewWillDisappear。我注释掉了viewWillDisappear版本,将这些版本留在viewDidUnload中,并且应用程序工作正常而不会崩溃。希望这有助于其他人。