3

TL:DR バージョン: NSZombieEnabled を使用して EXC_BAD_ACCESS エラーの原因を見つけたところ、ライブラリに保持されているよりも 1 つ多くのリリースがあることがわかりました。このライブラリがクラッシュの原因であると推測できますか?それとも、そのリリースが別のライブラリからの保持に関連付けられている可能性がありますか?

保持カウントが 0 に達した後、UITableViewCell サブクラス インスタンスがメッセージを取得するアプリで問題が発生しています。アプリを NSZombies で実行し、現在、retain/release 呼び出しをペアにして、エラーの発生元を正確に見つけようとしています。「Responsible Library」が QuartzCore に設定されていると、2 つの保持と 3 つのリリースしかないことに気付きました。その余分なリリース コールがアプリのクラッシュの原因になっているということですか? または、リリースが別のライブラリに関連付けられている可能性はありますか?

追加情報: セクション ヘッダーはタップ可能です。いずれかを選択すると、このセクションの行がテーブル ビューに挿入され、以前に表示されていた行は削除されます。つまり、一度に存在できるセクションは 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で発生します。

4

2 に答える 2

0

配列内のインデックス パスが無効な場合は、EXC_BAD_ACCESSその行でを取得できます (例: のセクション番号)。そして、それらに有効な値が含まれていることを確認する必要があります。endUpdates-1NSLogindexPathsToInsertindexPathsToDelete

于 2013-09-25T11:20:38.263 に答える