Notification Center - 옵저버 등록과 제거
var observer: NSObjectProtocol?
observer = NotificationCenter.default.addObserver(forName: UIApplication.userDidTakeScreenshotNotification, object: nil, queue: nil) { notification in
print("user take screenshot!")
NotificationCenter.default.removeObserver(observer!)
}
Notification Center
등록된 옵저버들에게 노티피케이션을 보낼 수 있는 클래스이다.
- 모든 애플리케이션은 default Notification Center 를 가지고 있다.
- 노티피케이션을 그룹화하기 위해 새로운 Notification Center 를 만들 수 있다.
- 싱글 프로세스에만 노티피케이션을 보낼 수 있기 때문에, 만약 다른 프로세스에 노티피케이션을 보내고 싶다면 Distributed NotifiactionCenter 를 사용해야 한다.
옵저버 등록하기
func addObserver(forName name: NSNotification.Name?,
object obj: Any?,
queue: OperationQueue?,
using block: @escaping (Notification) -> Void) -> NSObjectProtocol
Notifiaction 을 받아서 특정 블록을 실행하는 observer 를 등록하는 함수로, 각 매개변수에 대해서 알아보자
name
어떤 이름을 가진 Notification 을 받을지를 결정하는 매개변수. 만약 nil 로 준다면, 해당 이름을 기준으로 Notification 을 필터링하지 않는다.
object
옵저버에게 Notification 을 보내는 object, 즉 sender 를 의미한다. 만약 특정 sender 가 보내는 노티만 받고 싶다면, sender 를 등록하자. 만약 nil 으로 등록하면 노티피케이션 수신 기준으로 sender 를 사용하지 않는다.
queue
block 이 실행될 operation queue 를 의미한다. 만약 nil 이면, Notification 이 발행된 쓰레드에서 동기적으로 블록이 실행된다.
block
Notification을 수신할 때 실행될 블록, Notification Center 가 block 을 강하게 참조하고 있으므로, 꼭 removeObserver 로 옵저버를 제거하도록하자!
Return Value
Observer 처럼 행동하는 불명확 타입을 반환한다. Notification Center 가 해당 value 를 강하게 참조하고 있으므로, 꼭 removeObserver 로 옵저버를 지워주도록 하자.
옵저버 등록 예시
UIApplication 에 이미 기정의된, 유저가 스크린샷을 찍을 때 발생하는 Notification 이 있다. 해당 Notification 에 addObserver 를 통해 옵저버를 추가하고, 스크린샷을 찍을 때 print 하는 코드를 작성해보자.
NotificationCenter.default.addObserver(forName: UIApplication.userDidTakeScreenshotNotification, object: nil, queue: nil, using: { notification in
print("user take screenshot!")
})
userDidTakeScreenshotNotification 이름을 가지는 Notification 이 발생될 때마다, 우리가 넘겨준 print("user take screenshot") 클로저가 실행된다. 직접 확인해보자. 직접 아이폰을 연결해서 스크린샷을 찍으면, 실제로 잘 출력되는 것을 볼 수 있다.
옵저버 제거하기
옵저버를 등록했으면, 위에서 기술한 것과 같이 더 이상 옵저버가 필요없어졌을 때 옵저버를 삭제하는 작업이 필요하다.
func removeObserver(_ observer: Any,
name aName: NSNotification.Name?,
object anObject: Any?)
observer
Notification Center 의 dispatch table 에서 삭제할 옵저버를 넘겨준다.
aName
dispatch table 에서 삭제할 노티피케이션의 이름. 만약 nil 로 준다면 해당 이름을 기준 삼아 옵저버를 제거하지 않는다.
anObject
dispatch table 에서 삭제할 sender 오브젝트. 만약 어떤 object가 보내는 Notification 을 받는 옵저버들을 제거하고 싶을 때 넘겨주자.
옵저버 제거 예시
var observer: NSObjectProtocol?
observer = NotificationCenter.default.addObserver(forName: UIApplication.userDidTakeScreenshotNotification, object: nil, queue: nil) { notification in
print("user take screenshot!")
NotificationCenter.default.removeObserver(observer!)
}
addObserver 로 옵저버를 추가하면, 해당 옵저버가 반환값으로 넘어온다고 했다. 따라서 스크린샷 감지 옵저버를 등록하고, 클로저에서 해당 observer 를 Notification Center 에서 삭제하는 것으로 한 번만 스크린샷 찍는 것을 감지하는 코드를 작성했다.
실제로 앱을 실행해서 여러 번 스크린샷을 찍어도, user take screenshot 은 한 번만 출력되는 것을 확인할 수 있다.