http://ebcban.blog.me/30089133519
통보는 하나 이상의 객체가 어떤 이벤트를 받고 싶을때 사용한다. 델리게이트가 1:1 관계로 객체간에 긴밀하게 연결되어 있다면, 통보 서비스는 동적으로 임의적인 객체간의 연결이 가능하다.
어떤 객체가 관심 있는 이벤트에 대해서 통보를 받기 위해서는 통보 센터에 자신을 등록해야 한다. 다음 코드를 보자.
01: [[NSNotificationCenter defaultCenter]
02: addObserver:self
03: selector:@selector(launchFinished:)
04: name:UIApplicationDidFinishLaunchingNotification
05: object:nil];
위 코드는 임의의 객체가 UIApplicationDidFinishLaunchingNotification 라는 통보를 발생시키면 self 객체의 launchFinished 를 호출하도록 한다. 코드의 2행과 3행의 인자는 통보가 발생했을 때 호출할 메서드를 지정한다. 여기서 이벤트는 문자열로 구분된다. 그래서 UIApplicationDidFinishLaunchingNotification 도 문자열로 정의되어 있다.
5행의 object 인자는 감시할 개체를 지정하기 위한 것이다. 만약 nil 을 지정하면 모든 객체를 대상으로 이벤트를 감시하게 된다. 만약 5행의 object 를 nil 로 설정하지 않고 특정 객체를 지정해 주면, 그 객체가 일치하는 문자열의 통보를 발생시킬 때만 통보를 받을 수 있다.
통보 이벤트를 더이상 감시할 필요가 없을때는 다음과 같이 제거해야 한다.
01: [[NSNotificationCenter defaultCenter] removeObserver:self];
removeObserver 메서드로 자신(self)이 더이상 통보를 받지 않겠다고 설정한다.
<그림1> 도움말 문서의 통보 항목
클래스의 도움말 문서를 보면 그 클래스가 발생시키는 통보를 확인 할 수 있다. 예를들어 그림1과 같이 UIWindow 클래스의 도움말을 보자. Notifications 라는 항목으로 자신이 발생시키는 통보에 대해서 설명하고 있다. UIWindowDidBecomeVisibleNotification 와 같은 통보 이름은 클래스의 헤더파일에 문자열로 정의되어 있다.
만약 직접 작성한 클래스에서 통보를 발생시키고 싶다면 어떻게 할까 ? 무척간단하다.
01: [[NSNotificationCenter defaultCenter]
02: postNotificationName:@"myEventOccured" object:self];
NSNotificationCenter 의 postNotificationName 메서드를 이용하면 된다. object 인자는 누가 이 통보 이벤트를 발생시키는 지를 설정한다.
<그림2> 예제
그림2의 예제를 직접 구현해 보자. ObjectA,ObjectB,ObjectC 는 각각 event1, myEventOccured,모든 통보 이벤트(nil) 에 관심이 있다.
01: [[NSNotificationCenter defaultCenter]
02: addObserver:ObjectA
03: selector:@selector(myEventHandler:)
04: name:@"event1"
05: object: nil];
06:
01: [[NSNotificationCenter defaultCenter]
02: addObserver:ObjectB
03: selector:@selector(myEventHandler:)
04: name:@"myEventOccured"
05: object: nil];
06:01: [[NSNotificationCenter defaultCenter]
02: addObserver:ObjectC
03: selector:@selector(myEventHandler:)
04: name: nil
05: object: nil];
06:
ObjectC 는 name에 nil 을 설정했기 때문에 모든 이벤트를 통보받게 된다. 이제 객체X가 통보를 발생시킨다.
01: [[NSNotificationCenter defaultCenter]
02: postNotificationName:@"myEventOccured"
03: object:ObjectX
04: userInfo:[NSDictionary dictionaryWithObject:@”value1” forKey:@”data1”]
05: ];
위 코드가 실행되면 통보 센터는 ObjectX 에서 myEventOccured 통보가 발생했기 때문에, 이 통보를 감시하는 모든 객체의 메서드를 호출해 준다. 이때 감시 객체들은 ObjectX가 전달한 userInfo 딕셔너리 객체도 사용할 수 있다. 이벤트를 통보받는 메시지를 구현해 보자.
01: - (void) myEventHandler:(NSNotification *) notif
02: {
03: NSLog(@“%@ from %@”, [notif name], [notif object]);
04: NSDictionary *userInfo = [notif userInfo];
05: // userinfo 딕셔너리의 내용을 나열하자.
06: for (NSString *key in userInfo) {
07: NSLog(@“%@ = %@”, key, [userInfo objectForKey:key];
08: }
09: }
통보를 받으면 호출되는 이 메서드는 인자로 NSNotification 객체를 받는다. 이 객체는 통보에 대한 정보를 담고 있다. userInfo 속성은 통보를 보내는 객체가 추가 정보를 전달할 때 이용된다.
* 통보 큐
통보를 발생시킬때 호출하는 postNotificationName 메서드는 곧바로 모든 감시자의 메서드를 호출한다. 하지만 통보 큐를 이용하면 쓰레드가 유휴(Idle) 상태 일 때 메서드를 호출하게 만들 수 있다. 다음 코드를 보자.
01: [[NSNotificationCenter defaultCenter]
02: addObserver:objectA
03: selector:@selector(eventHandler:)
04: name:@"appLaunched" object:nil];
05:
06: [[NSNotificationQueue defaultQueue]
07: enqueueNotification:[NSNotification
08: notificationWithName:@"appLaunched"
09: object:self]
10: postingStyle:NSPostWhenIdle];
10행의 NSPostWhenIdle 옵션은 현재 쓰레드가 유휴상태일때 통보를 보내도록 한다.
'개발 > App Developer' 카테고리의 다른 글
Disclosure indicator , detail Disclosure Button (0) | 2010.09.01 |
---|---|
뷰 (0) | 2010.09.01 |
읽어보자-스마트폰과 위치기반서비스 (0) | 2010.09.01 |
구조체(CGPoint,CGSize,CGRect) -> 객체(NSDictionary) -> 구조체 (0) | 2010.09.01 |
Window and View (0) | 2010.09.01 |