본문 바로가기

code snippet

[iOS] 노티 옵저버 등록과 해제


노티에 등록된 감시 객체가 삭제되지 않는 문제가 발생! 수 시간의 디버깅 끝에 원인을 찾았다. 노티 센터에 등록한 옵저버와 옵저버를 삭제하는 코드에서의 옵저버 객체가 달랐던 것이다.


감시 객체를 삭제하는 코드는 다음과 같이 작성했다. 즉 self - 뷰 컨트롤러가 옵저버라고 생각하고 짰는데.. 옵저버를 블록 객체로 등록했었다.


NSNotificationCenter.defaultCenter().removeObserver(self)


이 기회에 좀 정리해본다.



== 객체를 옵저버로 사용


노티 발생 여부를 감시하는 옵저버(Observer)를 등록하는 방법은 다음과 같다. 이 메소드에서 노티 센터에 등록되는 옵저버는 observer 파라미터의 객체다.


// 옵저버 객체 : observer

func addObserver(observer: AnyObject, selector aSelector: Selector, name aName: String?, object anObject: AnyObject?)


다음은 viewWillAppear에서 뷰 컨트롤러 객체(self)를 옵저버로 등록하고, viewDidAppear에서 옵저버를 해제하는 코드다. 노티를 2번 발생시키지만 옵저버가 해제된 이후의 알림에는 반응이 없다. 즉 콘솔에 1개의 내용만 출력된다.



class ViewController: UIViewController {

  

  override func viewWillAppear(animated: Bool) {

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleNoti:", name: "NormalNoti", object: nil)

  }

  

  func handleNoti(noti : NSNotification) {

    println("Handling Noti")

  }

  

  override func viewDidAppear(animated: Bool) {    

    NSNotificationCenter.defaultCenter().postNotificationName("NormalNoti", object: nil)

    NSNotificationCenter.defaultCenter().removeObserver(self)

    NSNotificationCenter.defaultCenter().postNotificationName("NormalNoti", object: nil)    

  }

}


== 블록을 옵저버로 사용



다음 메소드는 클로저(블록)을 이용해서 옵저버를 등록하는 메소드다. 이 메소드에서 노티 객체는 메소드에서 반환된 객체가 옵저버가 된다.


// 옵저버 : 반환된 객체

func addObserverForName(name: String?, object obj: AnyObject?, queue: NSOperationQueue?, usingBlock block: (NSNotification!) -> Void) -> NSObjectProtocol


블록을 옵저버로 등록하고 해제하는 코드는 다음과 같다.



class ViewController: UIViewController {

  

  var blockNoti : AnyObject!

  

  override func viewWillAppear(animated: Bool) {

    blockNoti = NSNotificationCenter.defaultCenter().addObserverForName("BlockNoti", object: nil, queue: NSOperationQueue.mainQueue()) { (noti) -> Void in

      println("Block Noti Observer Works")

    }

  }

  

  override func viewDidAppear(animated: Bool) {

    NSNotificationCenter.defaultCenter().postNotificationName("BlockNoti", object: nil)

    NSNotificationCenter.defaultCenter().removeObserver(blockNoti)

    NSNotificationCenter.defaultCenter().postNotificationName("BlockNoti", object: nil)

  }


}





반응형