객관적인 C 클래스가 있습니다. 그 안에 init 메소드를 만들고 NSNotification을 설정했습니다.
//Set up NSNotification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(getData)
name:@"Answer Submitted"
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self]
이 수업 에서는 어디에 설정 합니까? 나는 a UIViewController
에 대해 그것을 viewDidUnload
메소드에 추가 할 수 있다는 것을 알고 있습니다. 그래서 방금 목표 c 클래스를 생성했다면 무엇을해야할까요?
답변
일반적인 대답은 “더 이상 알림이 필요하지 않은 즉시”입니다. 이것은 분명히 만족스러운 대답이 아닙니다.
관찰자 등록을 완전히 취소 할 수있는 마지막 기회이므로 관찰자로 사용하려는 클래스의 [notificationCenter removeObserver: self]
메서드 dealloc
에 호출을 추가하는 것이 좋습니다 . 그러나 이것은 알림 센터가 죽은 개체를 알리기 때문에 충돌로부터 만 보호합니다. 개체가 아직 알림을 적절하게 처리 할 수있는 상태가 아니거나 더 이상없는 경우 알림 수신으로부터 코드를 보호 할 수 없습니다. 이를 위해 … 위를 참조하십시오.
편집 (답이 내가 생각했던 것보다 더 많은 주석을 끌어내는 것 같기 때문에) 여기서 제가 말하려는 것은 알림 센터에서 관찰자를 제거하는 것이 가장 좋은시기에 대한 일반적인 조언을 제공하기가 정말 어렵습니다.
- 사용 사례 (어떤 알림이 관찰됩니까? 언제 전송됩니까?)
- 관찰자의 구현 (알림을받을 준비가 된 시점은 언제입니까? 더 이상 준비되지 않은 시점은 언제입니까?)
- 관찰자의 의도 된 수명 (보기 또는보기 컨트롤러와 같은 다른 개체에 연결되어 있습니까?)
- …
그래서 제가 생각해 낼 수있는 가장 일반적인 조언은 앱을 보호하는 것입니다. 적어도 한 번의 실패 가능성에 대비하여에서 removeObserver:
춤을 추십시오. dealloc
그것이 (객체의 삶에서) 마지막 지점이기 때문에 깨끗하게 할 수 있습니다. 이것이 의미하지 않는 것은 ” dealloc
이 호출 될 때까지 제거를 연기하면 모든 것이 잘 될 것입니다”입니다. 대신 개체가 더 이상 알림을받을 준비가되지 않거나 필요하지 않으면 즉시 관찰자 를 제거합니다 . 바로 그 순간입니다. 안타깝게도 위에서 언급 한 질문에 대한 답을 알지 못해서 그 순간이 언제인지 짐작조차 할 수 없습니다.
항상 안전하게 removeObserver:
객체를 여러 번 사용할 수 있습니다 (주어진 관찰자와의 첫 번째 호출을 제외하고 모두 nops가됩니다). 그러니 : dealloc
확실하게하기 위해 (다시) 생각해보세요 .하지만 무엇보다도 먼저 : 적절한 순간에하세요 (사용 사례에 따라 결정됨).
답변
참고 : 이것은 100 % 테스트 및 작동되었습니다.
빠른
override func viewWillDisappear(animated: Bool){
super.viewWillDisappear(animated)
if self.navigationController!.viewControllers.contains(self) == false //any other hierarchy compare if it contains self or not
{
// the view has been removed from the navigation stack or hierarchy, back is probably the cause
// this will be slow with a large stack however.
NSNotificationCenter.defaultCenter().removeObserver(self)
}
}
PresentedViewController
override func viewWillDisappear(animated: Bool){
super.viewWillDisappear(animated)
if self.isBeingDismissed() //presented view controller
{
// remove observer here
NSNotificationCenter.defaultCenter().removeObserver(self)
}
}
목표 -C
에서 iOS 6.0 > version
의 더 나은 것은에서 관찰자를 제거하기 위해 viewWillDisappear
같은 viewDidUnload
방법이 사용되지 않습니다.
[[NSNotificationCenter defaultCenter] removeObserver:observerObjectHere];
많은 배 더있다 remove observer
뷰가 제거 된 경우 navigation stack or hierarchy
.
- (void)viewWillDisappear:(BOOL)animated{
if (![[self.navigationController viewControllers] containsObject: self]) //any other hierarchy compare if it contains self or not
{
// the view has been removed from the navigation stack or hierarchy, back is probably the cause
// this will be slow with a large stack however.
[[NSNotificationCenter defaultCenter] removeObserver:observerObjectHere];
}
}
PresentedViewController
- (void)viewWillDisappear:(BOOL)animated{
if ([self isBeingDismissed] == YES) ///presented view controller
{
// remove observer here
[[NSNotificationCenter defaultCenter] removeObserver:observerObjectHere];
}
}
답변
iOS 9부터 더 이상 관찰자를 제거 할 필요가 없습니다.
OS X 10.11 및 iOS 9.0에서 NSNotificationCenter 및 NSDistributedNotificationCenter는 더 이상 할당이 취소 될 수있는 등록 된 관찰자에게 알림을 보내지 않습니다.
답변
관찰자가 뷰 컨트롤러 에 추가 된 경우에는 추가 viewWillAppear
하고 제거 하는 것이 좋습니다 viewWillDisappear
.
답변
-(void) dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
답변
일반적으로 나는 그것을 dealloc
방법에 넣었다 .
답변
dealloc을 사용할 수 없기 때문에 신속하게 deinit를 사용하십시오.
deinit {
...
}
Swift 문서 :
deinitializer는 클래스 인스턴스가 할당 해제되기 직전에 호출됩니다. init 키워드를 사용하여 intializer를 작성하는 방법과 유사하게 deinit 키워드를 사용하여 deinitializer를 작성합니다. Deinitializer는 클래스 유형에서만 사용할 수 있습니다.
일반적으로 인스턴스 할당이 취소 될 때 수동 정리를 수행 할 필요가 없습니다. 그러나 자체 리소스로 작업하는 경우 몇 가지 추가 정리를 직접 수행해야 할 수 있습니다. 예를 들어 사용자 정의 클래스를 만들어 파일을 열고 일부 데이터를 쓰는 경우 클래스 인스턴스가 할당 해제되기 전에 파일을 닫아야 할 수 있습니다.