문제
다양한 방법으로 데이터 전달하기
3. NotificationCenter로 전달하기
4. Closure로 전달하기
5. 장단점 정리
NotificatonCenter로 전달하기
3 - 1 화면 전환 시 데이터를 전달하는 데에 여러가지 방법이 있는데, 그 중 NotificationCenter를 사용해 데이터를 전달하는 방법을 알아보자.
NotificationCenter는 알림 발송 매커니즘(notification dispatch mechanism)이다. NotificationCenter는 알림이 게시(post)되면 등록된 옵져버에 알린다(broadcast). 알림을 받은 옵져버는 미리 설정된 메서드를 호출해 작업을 수행한다.
먼저 3의 ViewController에서 알림을 보내자. 알림을 보내기 위해서는 NotificationCenter의 post(name:object:userInfo:)을 사용해야한다. 화면 전환 버튼의 액션 함수에 post 메서드를 호출하고 이전화면으로 돌아가자.
+ NotificationCenter는 싱글톤으로, default 프로퍼티를 사용해 NotificationCenter 객체를 사용할 수 있다.
class NotificationCenterViewController: UIViewController {
@IBOutlet weak var contentLabel: UILabel!
@IBOutlet weak var contentTextField: UITextField!
var content: String?
override func viewDidLoad() {
super.viewDidLoad()
configureView()
}
private func configureView(){
self.contentLabel.text = content
}
//알림 게시
@IBAction func tapPreviousButton(_ sender: UIButton) {
NotificationCenter.default.post(
name: Notification.Name("Content"),
object: nil,
userInfo: ["content" : self.contentTextField.text as Any]
)
self.navigationController?.popViewController(animated: true)
}
}
- name: NSNotification.Name - 알림의 이름, 이 값으로 알림을 구분한다
- object: Any? - 알림을 게시할 객체
- userInfo: [AnyHashable : Any]? - 알림에 대한 옵셔널 정보가 들어있는 딕셔너리 타입의 사용자 정보, 전달할 데이터를 할당한다
- userInfo는 Any 타입이므로 데이터가 다른 타입이라면 형변환이 필요하다.
1의 ViewController에서는 위에서 생성한 알림을 받을 옵져버를 만들어야 한다. 옵져버는 NotificationCenter의 addObserver(_:selector:name:object:)를 사용해 생성할 수 있으며 알림을 받은 후 수행할 작업을 설정할 수 있다. 이 옵져버는 등록되어져 있는 객체가 메모리에서 해제되기 전 제거되어야 하는데, 등록한 곳에 따라 LifeCycle에 맞춰 제거하면 된다.
viewWillAppear - viewWillDisappear
viewDidLoad - deinit
옵져버를 등록할 때 알림을 받은 후 수행할 작업을 설정할 수 있는데, NotificationCenter가 NSObject타입이므로 Selector 타입의 메서드를 전달해야한다. Selector를 생성할 메서드는 Object-C 타입이라는 것을 명시해 줄 @objc 키워드를 사용한다.
class PropertyViewController: UIViewController {
...
//MARK: - 라이프 사이클
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(
self,
selector: #selector(assignContent(_:)),
name: Notification.Name("Content"),
object: nil)
}
...
//MARK: - objc
@objc private func assignContent(_ notification: Notification){
guard let userInfo = notification.userInfo else {return}
guard let content = userInfo["content"] as? String? else {return}
self.content = content
}
deinit {
NotificationCenter.default.removeObserver(self) //self에 등록되어있는 모든 옵져버 제거
}
}
- userInfo는 Any 타입이므로 형변환이 필요하다.
Remove Observer
'iOS' 카테고리의 다른 글
[ iOS ] contentConfiguration: TableView에 기본 Cell 사용하기 (iOS 14+) (0) | 2022.11.29 |
---|---|
[ iOS ] UIButton.Configuration 사용하기(1) - Init, Title (iOS 15) (0) | 2022.10.13 |
[ iOS ] 데이터 전달 : (2/5) DelegatePattern으로 전달하기 (0) | 2022.06.20 |
[ iOS ] 데이터 전달 : (1/5) Property로 전달하기 (0) | 2022.06.20 |
[ iOS ] 사진 선택 시 번호 표기(넘버링) 구현 (+ collectionView) (0) | 2022.06.15 |