NotificationCenter
NotificationCenter는 iOS에서 이벤트를 전파하는 데 사용되는 중요한 클래스이다. 이 클래스를 사용하면 여러 객체 간 이벤트를 효율적으로 전달하고 처리할 수 있다.
✅ 이벤트 전파 : 특정 이벤트가 발생했을 때 관련된 모든 객체에게 이를 알리는 역할을 한다. 이벤트는 이름 또는 식별자를 가지며, 이벤트가 발생했을 때 해당 이벤트에 등록된 모든 관찰자에게 알린다.
✅ 이벤트 등록과 해제 : addObserver(:selector:name:object:) 메소드를 사용해서 특정 이벤트에 대한 관찰자를 등록하고, removeObserver(:) 메소드를 사용하여 관찰자를 해제한다. 이를 통해 관찰자가 더 이상 필요하지 않을 때 메모리 누수를 방지할 수 있다.
✅ 이벤트 처리 : 이벤트가 발생하면 NotificationCenter는 등록된 관찰자에게 해당 이벤트를 전달한다. 관찰자는 이를 처리하기 위해 지정된 셀렉터 또는 클로저를 실행한다.
✅ 동기 및 비동기 이벤트 전달 : 기본적으로 이벤트는 동기적으로 전달되지만, DispatchQueue를 사용하여 비동기적으로 처리할 수 있다.
➡️ NotificationCenter는 주로 앱 내에서의 통신이나 상태 변화 등을 처리하는 데 사용된다. 예를 들어, 앱 내에서 데이터의 변경을 감지하거나, 사용자 인터페이스의 상태를 업데이트하는 등의 작업에 사용될 수 있다.
구현하기
private func setupNotificationObservers() {
NotificationCenter.default.addObserver(self, selector: #selector(handleCoreDataChange), name: NSNotification.Name.NSManagedObjectContextDidSave, object: nil)
}
@objc private func handleCoreDataChange() {
print("변경이 감지 되었습니다.")
}
1. NotificationCenter 클래스의 싱글톤 인스턴스인 default을 사용하여 NotificationCenter에 엑세스 한다.
2. addObserver 메소드를 호출하여 관찰자를 등록한다.
✅ self : 관찰자를 등록하는 객체.
✅ selector : 이벤트가 발생했을 때 호출될 메소드의 셀렉터
✅ name : 관찰할 이벤트의 이름이다.
📚NSManagedObjectContextDidSave : CoreData에서 NSManagedObjectContext가 변경되었음을 나타내는 노티피케이션이다.
✅ object : 이벤트를 발생시키는 객체를 지정한다.
따라서 이 코드는 NSManagedObjectContextDidSave 노티피케이션을 관찰하고, 이벤트가 발생했을 때 handleCoreDataChange를 호출하여 해당 이벤트를 처리한다. 이를 통해 CoreData의 변경을 감지하고 처리할 수 있다.
진행 중인 프로젝트에서 CoreData의 변경을 감지하는 것을 적용해보았다. 사용자가 책 기록을 추가하면 변경을 감지하여 다시 데이터를 fetch하여 UI를 Update하도록 하는 코드이다.
물론 이대로 사용해도 상관 없지만, 내 프로젝트는 Rx를 기반으로 하고 있다. Rx로 CoreData의 변경을 감지하는 코드를 구현해보자.
private func setupObservers() {
NotificationCenter.default.rx.notification(.NSManagedObjectContextDidSave, object: NSManagedObjectContext)
.subscribe(onNext: { notification in
print("변경이 감지되었습니다.")
})
.disposed(by: disposeBag)
}
NotificationCenter.default.rx.notification(.NSManagedObjectContextDidSave:Object:)를 사용하여 NSManagedObjectContextDidSave의 변경을 관찰하고, 이를 구독하여 변경을 처리한다.
CoreData Manager에서 관리하기
CoreData의 변경을 감지해야하는 곳이 많아지면 어떻게 해야할까? 똑같은 코드를 계속 작성 할 필요는 없다. CoreData Manager에 변경을 감지하는 메소드를 구현하여 필요한 곳에서 사용하면 된다.
class CoreDataManager {
static let shared = CoreDataManager()
private let notificationCenter: NotificationCenter
private init() {
notificationCenter = NotificationCenter.default
}
private var coreDataChangeHandler: (() -> Void)?
func observeCoreDataChanges(_ handler: @escaping () -> Void) {
coreDataChangeHandler = handler
notificationCenter.addObserver(self, selector: #selector(handleCoreDataChanges(_:)), name: NSNotification.Name.NSManagedObjectContextDidSave, object: nil)
}
@objc private func handleCoreDataChanges(_ notification: Notification) {
coreDataChangeHandler?()
}
}
핸들링을 클로저로 하여 사용하고자 하는 곳에서 핸들링을 구현하면 된다.
실제로 프로젝트에 적용한 모습이다.
이제 Rx로 구현하는 방법을 알아보자.
class CoreDataManager {
static let shared = CoreDataManager()
private let notificationCenter = NotificationCenter.default
func observeCoreDataChanges() -> Observable<Void> {
return Observable.create { observer in
let token = self.notificationCenter.addObserver(forName: NSNotification.Name.NSManagedObjectContextDidSave, object: nil, queue: nil) { _ in
observer.onNext(())
}
return Disposables.create {
self.notificationCenter.removeObserver(token)
}
}
}
}
구현하는 방법은 많지만 내가 구현한 방법은 위와 같다. CoreData의 변경을 감지하는 NotificationCenter를 사용해서 Observable을 생성한다. NotificaionCenter는 NSManagedObjectConextDidSave 노티피케이션을 관찰하고, 해당 노티피케이션이 발생하면 onNext이벤트를 방출한다. 메모리 누수를 방지하기 위해 addObserver에서 반환 된 token을 사용하여 옵저버를 제거한다.
실제로 적용한 모습이다. 구독하여 핸들링을 처리하면 된다.
'iOS > CoreData' 카테고리의 다른 글
[CoreData] CoreData Migration을 알아보자. (0) | 2024.04.29 |
---|