2

저는 iPhone 앱을 쓰고 있습니다. 네비게이션 스택 [EditCreatorController]의 뷰 컨트롤러에서 시작하여 [BMSStringPickerController]라는 사용자 정의 모달 뷰 컨트롤러를 제공합니다. Apple 가이드 라인에 따라 데이터를 첫 번째보기로 다시 전달하고 해당보기를 사용하여 모달보기를 닫는 데 대한 대리인 프로토콜 등을 만들었습니다. 나는 심지어 모달 컨트롤러로부터 예상되는 데이터를 얻었고 그것을 잘 무시할 수 있었다. 문제는 거의 내가 원래 뷰 컨트롤러에 걸릴 조치는모달보기를 닫은 후에 부모보기가 할당 해제 된 것처럼 보입니까?

같은 오류를 디버거에 리드, 그 시점에서입니다 - [EditCreatorController performSelector : withObject : withObject는 :] : 메시지가 할당이 해제 된 인스턴스로 전송 0x3a647f0

또는

- [EditCreatorController있는 tableView : willSelectRowAtIndexPath :] 모달 뷰 표시하면서 원래 뷰 컨트롤러 증발과 같은 다른 말로 해제 된 인스턴스 0x3c12c40

전송 메시지가 보인다. 두 대리자 콜백 중 어떤 것이 호출 되더라도 상관 없습니다. 여기에 대리인 콜백된다

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
if (indexPath.row == 1) { // selection on creator type row 

    // create a string picker to choose new creator type from list 
    BMSStringPickerController *picker = [[BMSStringPickerController alloc] initWithNibName:@"BMSStringPickerController" bundle:nil]; 
    picker.delegate = self; 
    picker.stringChoices = [NSArray arrayWithObjects:@"composer", @"lyricist", @"arranger", @"original artist", @"other", nil]; 
    picker.currentChoice = creator.type; 
    picker.title = @"Creator Type"; 

    // wrap it in a nav controller so we can get tile bar etc. (from VC prog guide p. 93) 
    UINavigationController *newNavigationController = [[UINavigationController alloc] 
                initWithRootViewController:picker]; 

    [self.navigationController presentModalViewController:newNavigationController animated:YES]; 
    [newNavigationController release]; 
    [picker release]; 

} 
} 

그리고 :

- (void)stringPickerController:(BMSStringPickerController *)picker didPickString:(NSString *)string { 
NSLog(@"received string back: %@", string); 
typeLabel.text = string; // only change the label for now; object only changes if done button pressed 
[self.tableView reloadData]; 
[self dismissModalViewControllerAnimated:YES]; 
} 

- (void)stringPickerControllerDidCancel:(BMSStringPickerController *)picker { 
NSLog(@"picker cancelled"); 
[self dismissModalViewControllerAnimated:YES]; 
} 

또 다른 이상한 것은 (아마도 실마리가) 비록 있다는 것입니다 여기에

모달 뷰를 호출하는 부모 컨트롤러에서 코드 "받은 문자열 다시"NSLog 메시지를 가져 와서 그것을 typeLabel.text (typeLabel 내 테이블보기의 레이블에 IBOutlet입니다) 할당 할 테이블을 다시로드 할 경우에도 나타나지 않습니다.

누구나 아이디어가 있습니까?

답변

2

delegatedeallocBMSStringPickerController에 게시 하시겠습니까?

+0

빙고! 마이클에게 감사드립니다. 한 번 당신이 그것을 지적한 피 묻은 명백한! 이것은 질문을 구걸합니다. 제가 거기에 그것을 공개하지 않으면, 지금 메모리 누출이 있습니까? 내 원래의 호출 뷰 (대리자)는 이제 추가로 보유하고있는 것으로 보입니다.아니면 아니겠습니까? 피커 객체의 선언은 다음과 같습니다. @property (assign) id delegate; 그래서 할당하지 않기 때문에 피커가 dismissModal 호출을 통해 사라지면 모든 것이 메모리 적으로 다시 깨끗한가요? (분명히, 나는 obj-c 메모리 관리에 대한 나의 이해를 깊게하고있다.) : –

+0

맞다 - 일단 속성이 "보유"또는 "복사"로 표시되지 않으면 유지되지 않고 공개 할 필요가 없다. 그것. 너는 그걸 무시 하는게 낫다. –

1

그것은 당신의 문제를 해결할 수 있지만, 내가 제대로 처리 할 리스폰 더 체인을 허용, (대의원 방법에서) 자체를 닫 피커를 말하는 제언 기각 :

[picker dismissModalViewControllerAnimated:YES]; 
1

기본 동작이있을 때 메모리 경고는 볼 수없는 모든보기 컨트롤러의보기를 해제합니다. 따라서 모달 뷰 컨트롤러에서 메모리 경고가 발생하면 상위 뷰 컨트롤러의 뷰가 언로드 될 수 있습니다.

이렇게되면 뷰 컨트롤러에 viewDidUnload가 호출되어 뷰에 보유한 모든 참조를 해제 할 수 있습니다. 보유하지 않은 참조가 있으면 뷰가 언로드 될 때 유효하지 않게됩니다. 네 사건에 이런 일이 일어 났을 까?

자세한 내용은 UIViewController reference Memory Management 섹션을 참조하십시오. UIViewController 메서드 didReceiveMemoryWarning:보기가 현재 표시되지 않은 경우보기를 해제 한 다음 viewDidUnload를 호출합니다.