2013-09-23 3 views
3

TL : DR 버전 : NSZombieEnabled를 사용하여 EXC_BAD_ACCESS 오류의 출처를 찾고 라이브러리에 보유하는 것보다 1 개 더 많은 릴리스가 있음을 확인했습니다. 이 라이브러리로 인해 크래시가 발생하거나 해당 라이브러리가 다른 라이브러리의 보관과 관련 될 수 있습니까?NSZombie - 라이브러리에서 라이브러리를 유지/릴리스해야합니까?

보유 개수가 0에 도달 한 후 메시지를 가져 오는 UITableViewCell 하위 클래스 인스턴스가있는 앱에 몇 가지 문제가 있습니다. NSZombies를 사용하여 앱을 실행했으며 현재 retain/release 호출을 페어로 사용하여 정확한 오류 위치를 찾으려고합니다. 에서 유래했다. 나는 "Responsible Library"가 QuartzCore로 설정된 상태에서 2 개의 유지 및 3 개의 릴리즈 만 있다는 것을 알게되었습니다. 그 여분의 릴리스 호출이 내 응용 프로그램을 중단시키는 원인이됩니까? 또는 릴리스가 다른 라이브러리에 보유를 보유 할 수 있습니까?

추가 정보 : 내 섹션 머리글을 사용할 수 있으며,이 섹션 머리글을 선택하면이 섹션의 행이 테이블보기에 삽입되고 이전에 표시되는 행이 삭제됩니다. 즉, 한 번에 하나의 섹션 만있을 수 있고 다른 모든 섹션에는 0 개의 행이 있어야합니다.

릴리스/I 페어링 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

좀비를 사용하도록 설정 한 후 프로젝트에서 좀비를 찾았습니까? – Manthan

+0

예, 내 UITableViewCell 하위 클래스 인스턴스 – johnyu

+0

그래서 좀비를 얻는 곳에서 객체를 놓지 마십시오. 객체가 코드에서 사용 중이며 이미 릴리스 한 객체를 사용하고 있기 때문에 이미 객체를 사용하고 있습니다. deallocated 그리고 thats 왜 좀비가 저기에 제기됩니다. – Manthan

답변

0

이 문제에 대한 해결책을 이미 발견했습니다. 비동기 요청이 끝난 후 테이블 셀의 하위 뷰 중 하나가 becomeFirstResponder를 호출하는 것 같습니다. 물론 그 순간에 세포가 이미 풀린다면 충돌이 일어난 것입니다. 나는 처음에는 문제가 보존 및 릴리스의 불균형 때문에 발생한다고 생각했지만 그렇지 않은 것 같습니다.

제목에있는 질문에 답하기 : NSZombieEnabled 인스트루먼트 앱으로 실행하면 이미 연결된 것으로 가정 할 수있는 일부 유지/릴리스 쌍을 페어링합니다. 내 앱 중 하나에서 Instruments는 QuartzCore에서 나온 릴리즈와 UIKit에서 유지를 결합하여 참가했습니다. 100 % 확신 할 수는 없지만 "Responsible library"태그가 동일하다는 것은 의무 사항이 아니라고 가정합니다.

TL : DR - 보유가 다른 라이브러리에서 오는 릴리스와 쌍을 이룰 수 있다고 확신합니다.

0

배열의 색인 경로가 유효하지 않은 경우 endUpdates 행에 EXC_BAD_ACCESS이 표시 될 수 있습니다 (예 : -1의 섹션 번호). NSLogindexPathsToInsertindexPathsToDelete이어야하며 값이 올바른지 확인하십시오.

+0

나는 이미 그랬지만 모든 것이 괜찮은 것 같았다. 잘못된 indexPath를 사용하면 오류 메시지가 나타납니다. 나는 그렇지 않습니다. – johnyu

+0

@johnyu 때로는 유효하지 않은'NSIndexPath' 값이'endUpdates'에서 정확히 EXC_BAD_ACCESS를 생성 할 것입니다. (그것이 내가 그 예외를 재현 할 수있는 유일한 방법입니다.) 이것이 제가 제안한 이유입니다. 그러나, 당신이'insertRowsAtIndexPaths'와'deleteRowsAtIndexPaths'에 전달한 값들이 유효하다는 것이 확실하다면, 그 값은 그 값이 아니어야합니다. 행운을 빕니다. – Rob