iOS에서 NotificationCenter(구 NSNotificationCenter) 사용법 정리
간편로그인을 구현하다 보면 화면이나 객체 간 이벤트 전달을 위해 NotificationCenter를 자주 사용합니다. 예전에는 NSNotificationCenter를 많이 사용했지만, 지금은 Swift 기반으로 API가 단순해졌고 옵저버 제거 방식도 바뀌었습니다.
특히 과거에는 옵저버를 제거하지 않아 중복 호출, 다중 Noti 발생 등의 문제가 자주 발생했습니다. 이 글에서는 레거시 Objective-C 방식부터 2025년 최신 Swift 방식, 그리고 비동기 처리(NotificationQueue)까지 한 번에 정리해 드립니다.
1. (레거시) Objective-C에서 NSNotificationCenter 사용법
1-1. Notification 보내기 (post)
// 데이터 전달용 userInfo
NSDictionary *dic = @{@"firstKey": @"전송할 객체"};
[[NSNotificationCenter defaultCenter]
postNotificationName:@"firstNotification"
object:self
userInfo:dic];
1-2. Notification 받기 (addObserver)
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(firstMethod:)
name:@"firstNotification"
object:nil];
- (void)firstMethod:(NSNotification *)notification {
id value = notification.userInfo[@"firstKey"];
}
1-3. 반드시 옵저버 제거 필요 (중요!)
레거시 방식에서는 반드시 옵저버 제거가 필요했습니다.
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
옵저버를 제거하지 않으면 다중 호출 또는 메모리 해제 후 크래시 발생이 흔했습니다.
2. 2025년 기준 최신 Swift 방식
Swift에서는 NotificationCenter API가 개선되었으며, 특히 iOS 9+부터는 block-based observer 사용 시 removeObserver가 필요 없습니다.
2-1. Notification 보내기
NotificationCenter.default.post(
name: .loginSuccess,
object: nil,
userInfo: ["userId": "1234"]
)
2-2. Notification 받기
let observer = NotificationCenter.default.addObserver(
forName: .loginSuccess,
object: nil,
queue: .main
) { notification in
if let userId = notification.userInfo?["userId"] as? String {
print("로그인 성공: \(userId)")
}
}
2-3. 블록 기반 옵저버는 제거가 자동 처리
addObserver(forName:object:queue:using:) 방식은 iOS가 내부적으로 자동 제거하므로 예전처럼 removeObserver를 호출하지 않아도 됩니다.
2-4. 그러나 필요하면 명시적으로 제거 가능
NotificationCenter.default.removeObserver(observer)
3. Notification의 동기 / 비동기 처리
3-1. 기본 방식(post)은 동기 처리
NotificationCenter.default.post()는 옵저버들의 콜백이 모두 끝나기 전까지 제어가 호출자에게 돌아가지 않는 동기(synchronous) 방식입니다.
3-2. 비동기 방식 필요 시
예전에는 다음처럼 performSelector + afterDelay(0) 방식으로 비동기 효과를 냈습니다.
[self performSelector:@selector(doComplexProcessing:)
withObject:notification.object
afterDelay:0.0f];
4. 고급 비동기 처리: NSNotificationQueue
NSNotificationQueue는 Notification을 비동기 큐에 넣는 방식이며, 동기/비동기를 선택할 수 있습니다.
NSNotification *noti =
[NSNotification notificationWithName:@"testNotification" object:nil];
[[NSNotificationQueue defaultQueue]
enqueueNotification:noti
postingStyle:NSPostWhenIdle];
postingStyle 옵션
- NSPostNow – 즉시(동기)
- NSPostWhenIdle – run loop idle 시점(비동기)
- NSPostASAP – 곧 ASAP 비동기 처리
5. 최신 기술: NotificationCenter + Combine
현재 시점에서 iOS에서는 Combine 기반 Notification 사용이 더욱 편리합니다.
import Combine
var cancellables = Set<AnyCancellable>()
NotificationCenter.default.publisher(for: .loginSuccess)
.sink { notification in
print("로그인 성공(Note): \(notification)")
}
.store(in: &cancellables)
이 방식은 옵저버 제거를 수동으로 할 필요 없이 cancellables의 생명주기에 따라 자동 관리됩니다.
정리
- NSNotificationCenter는 현재도 사용 가능하지만 NotificationCenter로 업데이트됨
- Objective-C 방식은 반드시 removeObserver 필요
- Swift block-based observer는 자동 제거 (메모리 관리 개선)
- 동기/비동기 처리 차이를 이해해야 다중 호출 문제를 방지할 수 있음
- Combine을 사용하면 더 안전하고 편리하게 처리 가능
과거에는 옵저버 제거 누락으로 인해 크래시가 많이 발생했지만 지금은 훨씬 단순하고 안전하게 Notification을 사용할 수 있습니다.
'IT·디지털 > IT 개발자 팁' 카테고리의 다른 글
| [iOS] iOS8 AlertView 텍스트 상단 정렬 문제와 해결 방법 (0) | 2014.10.10 |
|---|---|
| [iOS] iPhone에서 올바른 URL 인코딩 방법 (Objective-C & Swift 최신 정리) (0) | 2013.12.10 |
| IIS HTTP Err Connection_Dropped 오류의 원인 분석과 실제 해결 사례 (2) | 2013.11.26 |
| [iOS] WebView 백그라운드 투명 처리 (UIWebView → WKWebView 최신 방식 포함) (0) | 2013.10.16 |
| [iOS] 화면 밝기를 강제로 최대값으로 변경 후 다시 복원하는 방법 (2025 최신 기준) (1) | 2013.10.11 |