2014-10-09 7 views
0

탈퇴 한 대리인에게 메시지를 보내는 UITableView에 문제가 발생했습니다. tableView를 소유하고있는 UIViewController의 dealloc가 호출되면 tableView가 여전히 살아 있고 tableView가 해당 대리자에게 메시지를 보내고 있습니다. 이 충돌은 tableView의 소유자가 dealloc에서 tableview를 해제 할 때 delegate = nil을 설정하여 해결됩니다. 메모리 관리가 올바르게 수행되면 이것이 필요하지 않다고 생각합니다.개체를 보유하고있는 사람을 어떻게 찾을 수 있습니까?

누가 tableView를 보유하고 있는지 알아내는 방법을 알고 싶습니다.

알아낼 수있는 방법이 있습니까?

감사합니다.

답변

0

인스트루먼트 (Xcode에서 Product-> Profile 메뉴)로 프로젝트를 시작하고 누설을 선택하십시오. 그것은 생성, 보존, 해제, 자동 릴리즈, 할당 취소 된 모든 객체를 기록합니다. 거기에서 메모리 주소를 검색 할 수도 있습니다. 따라서 객체의 메모리 주소를 가져 오는 방법입니다 (예 : 그것을 콘솔로 출력 할 수 있습니다.대부분의 사람들이 알고하지 않습니다하지만 당신은 기기 내에서 콘솔을 볼 수 있습니다

enter image description here

2

tableView은 대리인을 정리 한 후에도 처리를 계속하고 있습니다. 델리게이트는 weak 참조 속성에 할당되므로 UITableView에 보유되지 않습니다. UITableView이 여전히 요소를로드하는 동안 ViewController을 접을 경우이 충돌이 표시됩니다. 할당 해제되는 클래스가 델리게이트 인 경우 .delegate = nil을 dealloc에 ​​할당하는 것이 가장 좋습니다.

+0

"대표가 약한 참조 속성에 할당 된 기억"- jQuery과에 대한 위임 @property로 설정 (비 원자 할당) id 델리게이트, 그 이유는 tableView 여전히 dealloced 개체에 메시지를 보낼 수 있습니다. – kazuochi

+0

맞습니다. -'UITableView'는 pre-ARC로 만들어 졌으므로'assign' =='weak'과'retain' =='strong'을 고려할 수 있습니다. 'UITableViewDelegate'가 할당 해제 된 후에 객체가 존재하지 않기 때문에'UITableView'는 더 이상 객체에 메시지를 보낼 수 없습니다. 그러나, 이전에'UITableViewDelegate'에 의해 점유 된 메모리 주소에있는 객체에 메시지를 보내려고 시도 할 수 있습니다; 이것은 대개 EXC_BAD_ACCESS가됩니다. –

2

이 크래시는 tableView 소유자가 dealloc에서 tableview를 해제 할 때 delegate = nil을 설정하면 해결됩니다. 메모리 관리가 올바르게 수행되면 이것이 필요하지 않다고 생각합니다. 대표단은 종종 기본 객체가 해제 될 때 그들은 자동으로 nil로 설정되어 있음을 의미하는 weak을 선언하고 있기 때문에, 오늘날 종종 사실이다

. 하지만 UITableView은 그보다 더 오래되었습니다. 그것은 사전 ARC 일에서 유래와 그 대리인이 선언 : 대리자가 해제 된 경우

@property(nonatomic, assign) id<UITableViewDelegate> delegate 

그래서, UITableView는 할당되지 않은 메모리를 가리 킵니다.

이러한 종류의 충돌은 일반적으로 화면 상에 나타나지 않을 때 tableview를 업데이트하려고한다는 것을 의미합니다. 제 경험에서 가장 흔한 원인은 당신이해서는 안되는 알림을 관찰하는 것입니다. viewWillAppear:에있는 알림을 확인하고 viewDidDisappear: 동안 모든 관측을 제거하고 싶습니다. 마찬가지로 당신이 오프 스크린 일 때 KVO를 관찰하면 안된다. (그러나 나는 종종 이런 종류의 충돌이 NSNotification을 가리키는 것을 발견한다.)

대리인 이외의 개체가 테이블 뷰에 직접 액세스하지 않도록해야합니다. 누구도 reloadData 등을 뷰/위임 관계 외부에서 호출해서는 안됩니다. 아무도 대리인의 IBOutlet 속성에 액세스해야합니다. 그런 종류의 일들이 이런 종류의 충돌을 가져옵니다. 델리게이트 외부의 누구도 테이블 뷰에 대한 참조를 가질 수 없습니다.

물론 백그라운드 스레드에서 테이블 뷰를 업데이트하지 않도록하십시오. 아마도 여기에는 해당되지 않습니다. 다른 종류의 충돌로 이어지는 경향이 있습니다. 그러나 또 하나의 가능성이 있습니다.

관련 문제