2010年10月15日金曜日

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

Observerパターン

ダイナミックObjective-C「デザインパターンをObjective-Cで - Observer (1)」
ダイナミックObjective-C「デザインパターンをObjective-Cで - Observer (2)」
ダイナミックObjective-C「デザインパターンをObjective-Cで - Observer (3)」

今回書く内容は、上の記事を参考にして「Cocoa Notification」と「キー値監視」による「監視」についてのことを自分なりに噛み砕いて適当に書いている。間違ってたらごめんなさい。

Observerパターンは、「監視」のためのパターンだそうです。
あるオブジェクトを監視して、そのオブジェクトに何らかの状態変化が起きたとき、変化が起こったことを知らせる。

「Cocoa Notification」と「キー値監視」は、その「監視」のための方法です。


Observer = オブザーバー、監視者


Observerパターンに登場するクラスは2つで、監視するクラスと監視されて通知を行うクラスだ。
  • 監視するクラスの方がObserverクラス
  • 監視されるクラスの方がSubjectクラス

例えば、データが更新される毎にグラフの表示が変わるような処理がある場合、
  • グラフ表示が、Observerとしてデータの変化を「監視する」
  • データ自体が、Subjectとして「監視される」側となり変化が起きたら「通知する」

例えば無理やり、あなた(Subject)とあなたの上司(Observer)として考えてみるとすると、
  • 上司は、Observerとして部下の管理をする。
  • あなたは、Subjectとしてなにかあったら上司に報告する。

具体的には、
  • あなたは与えられた仕事が完了したので、終わったことを上司に報告する。
  • あなたは体調が悪くなったので、早退したいことを上司に報告する。

みたいな。

いや~わかりにくいなぁ。



「監視者」がいて、監視される人として「あなた」がいる場合、「監視」として正しいのはどれ?
  1. 「監視者」が「あなた」の状態変化を「監視」し「通知」する。
  2. 「あなた」の状態が変化したら、「あなた」は「監視者」に「通知」する。
  3. 「あなた」の状態が変化したら、「通知」という方法で「監視者」に気づいてもらう。

正解は、
  1. × これは正しいように見えるけど、ちょっと違う。「監視者」が「監視」し「通知」もしてるのが違う。そもそも実は「監視者」は「監視」しない。「あなた」が「通知」する。
  2. ◯ これ正解。
  3. ◯ これも雰囲気はあってるかな。


混乱するね。
じゃぁ「監視」ってあるけど誰が監視してんの?ってことになるんだけど、結局は誰も監視してないんだよね。

だから「通知」を主として考えると、
  • 通知を受け取るクラスをObserverクラス
  • 通知をするクラスをSubjectクラス

って感じに頭で整理しちゃってもいいんじゃないかなとも思うんだけど。ダメかな。



「NSNotification + NSNotificationCenter」のこと
  • NSNotificationCenterのインスタンスは1つしかない。
  • NSNotificationCenterのインスタンスは1つしかないので、扱い方がシンプルであまり迷わなさそう。
  • 1つしかないNSNotificationCenterのインスタンスを使って、ObserverとSubjectをゆるーい感じで繋げて「監視」対応ができるようになっている。
  • 「通知」する側も「通知」を受け取る側も、1つしかないNSNotificationCenterのインスタンスを一緒になかよく使う感じで。


「キー値監視」のこと
  • 「キー値監視」はNSObjectのレベルで実装されている。
  • NSNotificationと比べた場合、「監視者」が「通知」を受けた後に実行するメソッドを指定することが出来ない。
  • キー値コーディングのsetValue:forKey:というメソッドで「通知」しているので、特に何もしなくとも自動的に通知が行われているように感じられる。これは、通知の乱発につながる場合があるらくい。
  • その実際は、自分でアクセサメソッドを実装してその中で手動での制御が必要になるかもしれない。


あーダメだ。ちゃんと理解できてないないない。
ない。

続く。

0 件のコメント:

コメントを投稿