본문 바로가기

Software/iOS & Objective-C

About...Notification...!!!

Notification에 대하여...

Notification은 하나 이상의 객체가 어떤 이벤트를 받고 싶을때 사용한다. 델리게이트가 1:1 관계로 객체간에 긴밀하게 연결되어 있다면, Notification 서비스는 동적으로 임의적인 연결이
가능하다.

어떤 객체가 관심 있는 이벤트에 대해서 Notification을 받기 위해선 Notification Center에 자신을 등록해야 한다. 다음 코드를 보자. 

01: [[NSNotificationCenter defaultCenter] 
02: addObserver:self 
03: selector:@selector(launchFinished:) 
04: name:UIApplicationDidFinishLaunchingNotification 
05: object:nil];

위 코드는 임의의 객체가 UIApplicationDidFinishLaunchingNotification 이라는 통보를 받생시키면 self 객체의 launchFinished 라는 메소드를 호출하도록 한다. 코드의 2행과 3행의 인자는
Notification이 발생했을때 호출할 메소드를 지정한다. 여기서 발생한 Notification에 대한것은
문자열로 구분되며, 따라서 UIApplicationDidFinishLaunchingNotification 은 문자열로 정의되어 있다.

5행의 object 인자는 감시할 개체를 지정하기 위한 것이다. 만약 nil 을 지정하면 모든 객체를 대상으로 이벤트를 감시하게 된다. 만약 5행의 object 를 nil 로 설정하지 않고 특정 객체를 지정해 주면, 그 객체가 일치하는 문자열의 통보를 발생시킬 때만 통보를 받을 수 있다.

Notification 이벤트를 더이상 감지할 필요가 없을때는 다음과 같이 제거한다.

01: [[NSNotificationCenter defaultCenter] removeObserver:self];

removeObserver 메서드로 자신(self)이 더이상 통보를 받지 않겠다고 설정한다.

 

만약 직접 작성한 클래스에서 통보를 발생시키고 싶다면 어떻게 할까 ? 무척간단하다.

01: [[NSNotificationCenter defaultCenter] 
02: postNotificationName:@"myEventOccured" object:self];

NSNotificationCenter 의 postNotificationName 메서드를 이용하면 된다. object 인자는 누가 이 통보 이벤트를 발생시키는 지를 설정한다.

<그림2> 예제

그림2의 예제를 직접 구현해 보자. ObjectA,ObjectB,ObjectC 는 각각 event1, myEventOccured,모든 Notification 이벤트(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 을 설정했기 때문에 모든 이벤트를 Notification 받게 된다. 이제 객체X가 Notification을 발생시킨다.

01: [[NSNotificationCenter defaultCenter]

02: postNotificationName:@"myEventOccured"

03: object:ObjectX

04: userInfo:[NSDictionary dictionaryWithObject:@”value1” forKey:@”data1”]

05: ];

위 코드가 실행되면 Notification Center 는 ObjectX 에서 myEventOccured 통보가 발생했기 때문에, 이 Notification 를 감시하는 모든 객체의 메서드를 호출해 준다. 이때 감시 객체들은 ObjectX가 전달한 userInfo 딕셔너리 객체도 사용할 수 있다. 이벤트를 Notification 을 받는 메시지를 구현해 보자.

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: }

Notification 을 받으면 호출되는 이 메소드는 인자로 NSNotification 객체를 받는다. 이 객체는 Notification에 대한 정보를 담고 있다. userInfo 속성은 Notification 을 보내는 객체가 추가 정보를 전달할 때 이용된다.

* Notifification Queue

Notification 을 발생시킬때 호출하는 postNotificationName 메소드는 곧바로 모든 감시자의 메소드를 호출한다. 하지만 Notification Queue를 이용하면 쓰레드가 유휴(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 옵션은 현재 쓰레드가 유휴상태일때 통보를 보내도록 한다.

반응형