NSZombie - 保留/释放呼叫是否与库配对?

时间:2013-09-23 10:48:28

标签: iphone ios uitableview ios7 nszombie

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上发生错误。

2 个答案:

答案 0 :(得分:0)

如果数组中的索引路径无效(例如,EXC_BAD_ACCESS的部分编号),则可以在endUpdates行获得-1。您应NSLog indexPathsToInsertindexPathsToDelete,并确保其中包含有效值。

答案 1 :(得分:0)

我已经找到了解决此问题的方法。看来,在异步请求结束后,表格单元的一个子视图正在调用becomeFirstResponder。当然如果那个时刻已经释放了这个小区,就会发生崩溃。我刚开始假设问题是由于保留和释放的不平衡,但看起来不是这样。

并回答标题中的问题:当运行NSZombieEnabled Instruments应用程序已经配对一些保留/释放时它可以假设它们已连接。在我的应用程序的其中一个运行中,Instruments加入配对,来自QuartzCore的版本来自UIKit的保留。虽然我不能100%确定它是正确的,但我认为“负责任的图书馆”标签是相同的并不是强制性的。

TL:DR - 我很确定retain可以与来自另一个库的版本配对。