2

UIKeyboardWillHideNotification에 대해 듣고 싶은 간단한 viewController가 있습니다. 따라서 다음 코드가 있습니다.ViewWillAppear 및 ViewWillDisapper와 관련하여 NSNotificationCenter

- (void) viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(keyboardWillBeHidden) 
               name:UIKeyboardWillHideNotification object:nil]; 
} 

- (void) keyboardWillBeHidden 
{ 
    [self.scrollView setContentOffset:CGPointMake(0, 0) animated:YES]; 
} 

알림 센터 관찰자로 viewController를 제거 할시기를 결정하려고합니다. 이 충분한가

- (void) viewWillDisappear:(BOOL)animated 
{ 
    [super viewWillDisappear:animated]; 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 

: 난 단지 따라서 나는 다음을 추가하는 방법에 대해 생각하고는의 ViewController 화면에있을 때 UIKeyboardWillHideNotification에 대해 알아야 할? viewController가 여전히 화면에있는 동안 viewDidUnload 또는 dealloc이 호출 될 가능성이 있습니까? 내 응용 프로그램의 흐름에 매우 기본적인 UINavigationController을 사용하고 있습니다.

+0

왜 'dealloc'에서 Observer를 제거하지 않으시겠습니까? –

+0

viewcontroller가 화면을 벗어나는 동안 알림에 대해 알 필요가 없다는 점을 감안하면 다소 과도한 것 같습니다. – Nosrettap

답변

5

틀렸다 나에게 깨끗하고 대칭 해결책이 될 것으로 보인다. viewWillAppeardealloc 전에 여러 번 호출 할 수

주 (예 : 다른 뷰 컨트롤러는 VC으로 푸시하면, 또는 당신은 탭 표시 줄 컨트롤러 사이를 전환합니다.) 당신이 viewWillAppear에 통지를 등록하고 만 dealloc에서 등록을 취소하는 경우 중복 등록 (Warning for iOS/iPhone users about duplicate NSNotification observations 비교)이 발생하고 등록 된 선택기가 단일 통지 이벤트에 대해 여러 번 호출됩니다.

는 I 실제로 관찰자 블록 기반 등록 방법 다시 관찰자를 제거하기 위해 사용되는, 불투명 한 객체를 반환

addObserverForName:object:queue:usingBlock: 

을 선호한다. 이 반환 값을 뷰 컨트롤러의 인스턴스 변수에 저장하면 관찰자가 이미 등록되었는지 여부를 추적하여 중복 등록을 방지하는 데 도움이됩니다.

+0

그래서'addObserverForName' 메서드를 사용할 때'viewWillAppear'와'viewWillDisapper'에 넣을 수 있을까요? – Nosrettap

+0

@Nosrettap : 예. 그래서이 경우에 큰 차이를 만들지는 않습니다. 나는 이것을 좀 더 복잡한 상황에 대한 일반적인 언급으로 언급했습니다. 그리고 저는 블록 기반의 방법을 좋아합니다! –

+0

@MartinR 당신은'addObserverForName : object : queue : usingBlock :'으로 구현 예제를 가지고 있습니까? 많은 감사 –

0

직접 질문에 대답하려면 직접 전화하지 않는 한보기가 화면에 표시되는 동안 dealloc이 호출되지 않습니다.

dealloc은 viewController를 가리키는 강력한 포인터가 없을 때만 호출됩니다.

Anoop Vaidya에서 알 수 있듯이

, dealloc에 removeObserver을 넣어 당신의 ViewController 화면에있는 동안 dealloc가 호출되지 않습니다 것을 확신 할 수 완전히 행할 그리고 그것은 않는 경우 ... 잘은 제거보다 훨씬 더 큰 문제가 옵저버

편집 : 실제로 코멘트에 답장을 보낼 수 없기 때문에 viewController가 화면에서 꺼지면 실제로 할당이 취소됩니다. 그런 다음 화면에 다시 호출 될 때 다시 인스턴스화됩니다.

편집 : 나는 viewWillAppear에 통지를 등록 및 viewWillDisappear에 등록을 해제

+0

보기 컨트롤러가 오프 스크린 일 때 자동으로 할당 해제되고 다시 인스턴스화되지 않습니다. 뷰가 뷰 컨트롤러에 대한 강력한 참조를 가지지 않기 때문에 뷰가 화면 상에있는 동안 뷰 컨트롤러를 할당 해제하는 것이 가능합니다. 이것은 일반적으로 ARC에서 발생하지 않아야합니다. 그러나 vc의 뷰를 수동으로 계층 구조에 추가하는 경우 vc가 자동으로 리 릴리스되면 매우 쉽게 발생할 수 있습니다. – omz

+0

@omz : 두 번째 문장을 이해하지 못합니다. 뷰 컨트롤러가 뷰가 여전히 표시되어있는 동안 할당이 해제됩니다. 보기 컨트롤러 계층의 어딘가에있는 동안보기 컨트롤러에 대한 강력한 참조가 없어야합니까? - 네, 방금 의견을 보았습니다. 나는 ARC에서만 생각하고 있었다. –

+0

Mah, 나도 Stanford 강의에서 들었을 것으로 생각했지만 여전히 대부분 멍청하다. – Pinwheeler

관련 문제