2010年10月15日金曜日

「Cocoa Notification (NSNotification,NSNotificationCenter)」と「キー値監視」(2)

「Cocoa Notification (NSNotification,NSNotificationCenter)」を実際に試してみることにする。

新規プロジェクトをView-based Applicationを選択して名前をMyNotificationとして作成してます。

新規ファイル追加で、NSObjectを継承したMyNotificationを作成しています。

以下、編集したファイルの中身です。
なるべく簡潔に分かりやすくを心がけたつもり。


  1. //  MyNotificationViewController.h  
  2.   
  3. #import <UIKit/UIKit.h>  
  4.   
  5. @interface MyNotificationViewController : UIViewController {  
  6. }  
  7.   
  8. @end  


  1. //  MyNotificationViewController.m  
  2.   
  3. #import "MyNotificationViewController.h"  
  4. #import "MyNotification.h"  
  5.   
  6. @implementation MyNotificationViewController  
  7.   
  8. /* 
  9.  * 通知受け取ったときに呼ばれる処理 
  10.  */  
  11. - (void)owatayo  
  12. {  
  13.  NSLog(@"メインスレッド:通知owataを受け取ってowatayoメソッドを実行したよ。");  
  14. }  
  15.   
  16. - (void)viewDidLoad  
  17. {  
  18.     [super viewDidLoad];  
  19.   
  20.  NSLog(@"メインスレッド:処理開始");  
  21.   
  22.  // ここでは、通知を受けるObserverをselfとし、通知するSubjectをmyNotificationとする。  
  23.  // 新しいスレッドをたて、その新スレッドからの通知を受け取れることの確認によって「監視」のテストとする。  
  24.  MyNotification *myNotification = [[[MyNotification alloc] init] autorelease];  
  25.    
  26.  // NSNotificationCenterのインスタンスに、  
  27.  // addObserver : 通知を受け取るオブジェクト(ここでは自分自身)  
  28.  // selector : 通知を受けたときに実行するメソッド  
  29.  // name : 通知される通知名  
  30.  // object : どのオブジェクトからの通知を受け取るのか指定できる。nilであれば限定しない。  
  31.  NSNotificationCenter *center;  
  32.  center = [NSNotificationCenter defaultCenter];  
  33.  [center addObserver:self selector:@selector(owatayo) name:@"owata" object:myNotification];  
  34.    
  35.  // 新しいスレッドをたて、myNotificationのmyWorkメソッドを実行する。  
  36.  [NSThread detachNewThreadSelector:@selector(myWork) toTarget:myNotification withObject:nil];  
  37.   
  38.  NSLog(@"メインスレッド:処理終了");  
  39. }  
  40.   
  41. - (void)didReceiveMemoryWarning {  
  42.     [super didReceiveMemoryWarning];  
  43. }  
  44.   
  45. - (void)viewDidUnload {  
  46. }  
  47.   
  48. - (void)dealloc {  
  49.     [super dealloc];  
  50. }  
  51.   
  52. @end  


  1. //  MyNotification.h  
  2.   
  3. #import <Foundation/Foundation.h>  
  4.   
  5. @interface MyNotification : NSObject {  
  6. }  
  7.   
  8. - (void)myWork;  
  9. - (void)didMyWork;  
  10.   
  11. @end  


  1. //  MyNotification.m  
  2.   
  3. #import "MyNotification.h"  
  4.   
  5. @implementation MyNotification  
  6.   
  7. /* 
  8.  * 新スレッドでの処理 
  9.  */  
  10. - (void)myWork  
  11. {  
  12.  NSLog(@"新スレッド:処理開始");  
  13.  NSAutoreleasePool *pool;  
  14.  pool = [[NSAutoreleasePool alloc] init];  
  15.    
  16.  for (int i=0; i<5; i++) {  
  17.   [NSThread sleepForTimeInterval:1.0];  
  18.   NSLog(@"新スレッド:%d", i);  
  19.  }  
  20.    
  21.  [self didMyWork];  
  22.  [pool release];  
  23.  NSLog(@"新スレッド:処理終了");  
  24.  [NSThread exit];  
  25. }  
  26.   
  27. /* 
  28.  * 新スレッド終了するときの通知させる処理 
  29.  */  
  30. - (void)didMyWork  
  31. {  
  32.  // 通知を受け取る側では以下のようにobserverをNSNotificationCenterに追加している。  
  33.  // NSNotificationCenter *center;  
  34.  // center = [NSNotificationCenter defaultCenter];  
  35.  //[center addObserver:self selector:@selector(owatayo) name:@"owata" object:myNotification];  
  36.  //   
  37.  // name:@"owata" と notificationWithName:@"owata" で指定している @"owata" をキーとして通知のやりとりを行う。  
  38.  // 後は、NSNotification の postNotification: で通知を送れば、勝手に通知を受け取ってくれる。  
  39.  NSNotification *notification;  
  40.  notification = [NSNotification notificationWithName:@"owata" object:self userInfo:nil];  
  41.    
  42.  NSLog(@"新スレッド:通知を送るよ。通知の名前はowataだよ。");  
  43.  NSNotificationCenter *center;  
  44.  center = [NSNotificationCenter defaultCenter];  
  45.  [center postNotification:notification];  
  46. }  
  47.   
  48. @end  

こんな感じにログがでるはず。

2010-10-15 18:51:43.333 MyNotification[2310:207] メインスレッド:処理開始
2010-10-15 18:51:43.336 MyNotification[2310:5c03] 新スレッド:処理開始
2010-10-15 18:51:43.336 MyNotification[2310:207] メインスレッド:処理終了
2010-10-15 18:51:44.337 MyNotification[2310:5c03] 新スレッド:0
2010-10-15 18:51:45.338 MyNotification[2310:5c03] 新スレッド:1
2010-10-15 18:51:46.339 MyNotification[2310:5c03] 新スレッド:2
2010-10-15 18:51:47.341 MyNotification[2310:5c03] 新スレッド:3
2010-10-15 18:51:48.342 MyNotification[2310:5c03] 新スレッド:4
2010-10-15 18:51:48.343 MyNotification[2310:5c03] 新スレッド:通知を送るよ。通知の名前はowataだよ。
2010-10-15 18:51:48.344 MyNotification[2310:5c03] メインスレッド:通知owataを受け取ってowatayoメソッドを実行したよ。
2010-10-15 18:51:48.345 MyNotification[2310:5c03] 新スレッド:処理終了


追記:赤文字の部分にちょっと注意が必要そうなので、次の記事でそのこと書く。今回書いたサンプルコードではスレッド・セーフになってなさそう。

あれ?もしかして、NSNotification と NSNotificationCenter 使うと超簡単だったりするんじゃないの?

続く。

0 件のコメント:

コメントを投稿