2022. 12. 8. 23:17ㆍIOS
NotificationCenter
NotificationCenter는 앱 내에서 메세지를 던지고 필요한 곳에서 이 메세지를 받아 사용할 수 있는 기능을 수행한다. 좀 구체적으로 설명을 하자면 이벤트 발생시 Notification post하는 파트와 Notification을 받아 할 일을 수행하는 observer로 구성되며 이 옵저버는 특정 이벤트만을 기다리며 이벤트가 발생할 때만 불린다. 등록된 observer들에게 동시에 notification을 전달할 수 있으며, NotificationCenter는 Notification이 발송되면 옵저버가 이를 처리할 때까지 동기적으로 진행된다. NotificationCenter를 이용한 데이터 넘기기는 비교적 적은 코드로 앱 내의 어느 곳에 있는 객체든지 상호작용을 할 수 있다는 장점을 가지고 있다. 보통 백그라운드 작업의 결과, 비동기 작업의 결과 등 현재 작업의 흐름과 다른 흐름의 작업으로부터 이벤트를 받을 때 사용된다.
Notification
NotificationCenter를 통해 정보를 저장하기 위한 구조체이며 다음과 같이 구성되어 있다.
var name: Notification.Name
var object: Any?
userInfo: [AnyHashable : Any]?
- var name: Notification.Name
전달하고자 하는 notification의 이름으로 식별자 역할을 한다.
- var object: Any?
발송자가 옵저버에게 전달하고자 하는 객체로 전달하고자 하는 객체를 의미한다.
- userInfo: [AnyHashable : Any]?
notification과 관련된 값 또는 객체의 저장소 등 추가적인 정보를 보내는 데 사용된다.
NotificationCenter : Post, addObserver
원하는 이벤트에 맞춰서 post 매서드를 이용해 코드를 작성하면 NotificationCenter에 해당 name을 식별자로 한 Notification이 발송된다.
NotificationCenter.default.post(
name: Notification.Name("key"),
object: data,
userInfo: ["extra_data" : extra_data]
)
옵저버는 addObserver 매서드로 만들 수 있으며 다음과 같이 구성되어 있다.
func addObserver(
Any, // 옵저버 역할을 수행할 객체
selector: Selector, // 옵저버가 실행할 함수
name: NSNotification.Name?, // Notification의 name(식별자)
object: Any? // 넘겨진 데이터
)
따라서 위에서 작성한 post를 받기 위해서는 다음과 같이 작성하면 된다.
NotificationCenter.default.addObserver(
self,
selector: #selector(editDiarysetNotification(_:)),
name: Notification.Name("editDiary"),
object: nil
)
@objc func doSomething(_ notification : Notification) {
guard let data = notification.object as? String else {return}
print(data)
}
extension NotificationCenter.Name
위에 작성된 것처럼 코드를 작성하여도 되지만, 식별자인 name의 값을 까먹거나 맞춤법 실수로 버그가 발생할 때가 종종있다. 이러한 사고를 줄이고 더 쉽게 코드를 작성하기 위한 팁으로 extension NotificationCenter.Name 을 사용할 수 있다.
extension Notification.Name {
static let NotificationName = Notification.Name(rawValue: "namekey")
}
이를 이용하면 이전의 소개했던 post와 addObserver 코드를 다음과 같이 바꿀 수 있다.
NotificationCenter.default.post(
name: .NotificationName,
object: data,
userInfo: ["extra_data" : extra_data]
)
NotificationCenter.default.addObserver(
self,
selector: #selector(editDiarysetNotification(_:)),
name: .NotificationName,
object: nil
)
removeObserver
만일 특정 post에 대해 여러 옵저버를 만든다면 버그가 발생할 가능성이 많다. 따라서 필요가 없어진 observer는 지워야 할 필요가 있다! 따라서 앱의 생명주기를 사용해 필요한 때에 등록시키고 없애는 과정이 필요하다. 많은 분들이 willdisappear 함수를 사용하여 제거한다.필자는 deinit을 이용해 제거해 보았다.
deinit {
NotificationCenter.default.removeObserver(self)
}
'IOS' 카테고리의 다른 글
[IOS / Swift] DispatchQueue.main (0) | 2022.12.14 |
---|---|
[IOS / Swift] Codabler을 이용한 encoding, decoding (0) | 2022.12.14 |
[IOS] 데이터저장소 UserDefault (0) | 2022.12.07 |
[IOS] UIDatePicker 사용하기(DateFormatter) (0) | 2022.12.06 |
[IOS] UITextView 테두리칠하기(border) (0) | 2022.12.05 |