TL:DR版本:我使用NSZombieEnabled查找EXC_BAD_ACCESS错误的来源,并看到一个库有1个以上的版本而不是保留。我可以假设此库导致崩溃,或者该版本是否可以与另一个库的保留相关联?
我在我的应用程序中遇到一些问题,UITableViewCell子类实例在其保留计数达到0后获取消息。我使用NSZombies运行应用程序,我正在尝试配对保留/释放调用以查找错误源自何处从。我注意到只有2个保留和3个版本,“Responsible Library”设置为QuartzCore。这是否意味着额外的释放调用会导致我的应用程序崩溃?或者版本是否可能与另一个库中的保留相关联?
其他信息: 我的节标题是可点击的,当选择一个时,此节的行将插入到表视图中,并删除任何以前可见的行。换句话说,一次只能有1个部分有1行,所有其他部分必须有0行。
我配对的QuartzCore的释放/保留调用是:
CALayer layoutSublayers (retains)
CA::Layer::layout_if_needed(CA::Transaction*) (releases)
没有一对的释放是:
CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*)
我遇到崩溃的确切行是endUpdates行:
- (void)sectionHeaderView:(SectionHeaderView *)sectionHeaderView sectionOpened:(NSInteger)sectionOpened {
SectionInfo *sectionInfo = [self.sectionInfoArray objectAtIndex:sectionOpened];
sectionInfo.open = YES;
NSMutableArray *indexPathsToInsert = [[NSMutableArray alloc] init];
[indexPathsToInsert addObject:[NSIndexPath indexPathForRow:0 inSection:sectionOpened]];
/*
Create an array containing the index paths of the rows to delete: These correspond to the rows for each quotation in the previously-open section, if there was one.
*/
NSMutableArray *indexPathsToDelete = [[NSMutableArray alloc] init];
NSInteger previousOpenSectionIndex = self.openSectionIndex;
if (previousOpenSectionIndex != NSNotFound) {
SectionInfo *previousOpenSection = [self.sectionInfoArray objectAtIndex:previousOpenSectionIndex];
previousOpenSection.open = NO;
previousOpenSection.category.model = nil;
[previousOpenSection.headerView toggleOpenWithUserAction:NO];
[indexPathsToDelete addObject:[NSIndexPath indexPathForRow:0 inSection:previousOpenSectionIndex]];
}
// Style the animation so that there's a smooth flow in either direction.
UITableViewRowAnimation insertAnimation;
UITableViewRowAnimation deleteAnimation;
if (previousOpenSectionIndex == NSNotFound || sectionOpened < previousOpenSectionIndex) {
insertAnimation = UITableViewRowAnimationTop;
deleteAnimation = UITableViewRowAnimationBottom;
}
else {
insertAnimation = UITableViewRowAnimationBottom;
deleteAnimation = UITableViewRowAnimationTop;
}
NSIndexPath *indexToDelete = [indexPathsToDelete firstObject], *indexToInsert = [indexPathsToInsert firstObject];
if (indexToDelete == nil) {
NSLog(@"no row to delete");
}
else {
NSLog(@"deleting row %d section %d", [indexToDelete row], [indexToDelete section]);
}
NSLog(@"inserting row %d section %d", [indexToInsert row], [indexToInsert section]);
// Apply the updates.
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:indexPathsToInsert withRowAnimation:insertAnimation];
[self.tableView deleteRowsAtIndexPaths:indexPathsToDelete withRowAnimation:deleteAnimation];
[self.tableView endUpdates]; // this is the crash.
self.openSectionIndex = sectionOpened;
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:sectionOpened] atScrollPosition:UITableViewScrollPositionNone animated:YES];
}
iOS7上发生错误。
答案 0 :(得分:0)
如果数组中的索引路径无效(例如,EXC_BAD_ACCESS
的部分编号),则可以在endUpdates
行获得-1
。您应NSLog
indexPathsToInsert
和indexPathsToDelete
,并确保其中包含有效值。
答案 1 :(得分:0)
我已经找到了解决此问题的方法。看来,在异步请求结束后,表格单元的一个子视图正在调用becomeFirstResponder。当然如果那个时刻已经释放了这个小区,就会发生崩溃。我刚开始假设问题是由于保留和释放的不平衡,但看起来不是这样。
并回答标题中的问题:当运行NSZombieEnabled Instruments应用程序已经配对一些保留/释放时它可以假设它们已连接。在我的应用程序的其中一个运行中,Instruments加入配对,来自QuartzCore的版本来自UIKit的保留。虽然我不能100%确定它是正确的,但我认为“负责任的图书馆”标签是相同的并不是强制性的。
TL:DR - 我很确定retain可以与来自另一个库的版本配对。