1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
// /** *
NotificationObserver *
观察者类 *
这个类在NotificationCenter的addObserver中会自动创建,不需要你去使用它。 **/ class CC_DLL NotificationObserver : public Ref { private : Ref* _target; // 观察者主体对象 SEL_CallFuncO _selector; // 消息回调函数 std::string _name; // 消息名称 Ref* _sender; // 消息传递的数据 public : // 创建一个观察者对象 NotificationObserver(Ref *target, SEL_CallFuncO selector, const std::string& name, Ref *sender); // 当post发布消息时,执行_selector回调函数,传入sender消息数据 void performSelector(Ref *sender); }; /** *
NotificationCenter *
消息订阅/发布中心类 */ class CC_DLL __NotificationCenter : public Ref { private : // 保存观察者数组 NotificationObserver __Array *_observers; public : // 获取单例对象 static __NotificationCenter* getInstance(); static void destroyInstance(); // 订阅消息。为某指定的target主体,订阅消息。 // target : 要订阅消息的主体(一般为 this) // selector : 消息回调函数(发布消息时,会调用该函数) // name : 消息名称(类型) // sender : 需要传递的数据。若不传数据,则置为 nullptr void addObserver(Ref* target, SEL_CallFuncO selector, const std::string& name, Ref* sender); // 发布消息。根据某个消息名称name,发布消息。 // name : 消息名称 // sender : 需要传递的数据。默认为 nullptr void postNotification( const std::string& name, Ref* sender = nullptr); // 退订消息。移除某指定的target主体中,消息名称为name的订阅。 // target : 主体对象 // name : 消息名称 void removeObserver(Ref* target, const std::string& name); // 退订消息。移除某指定的target主体中,所有的消息订阅。 // target : 主体对象 // @returns : 移除的订阅数量 int removeAllObservers(Ref* target); }; // |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
// bool HelloWorld::init() { if ( !Layer::init() ) return false ; // 订阅消息 addObserver // target主体对象 : this // 回调函数 : getMsg() // 消息名称 : "test" // 传递数据 : nullptr NotificationCenter::getInstance()->addObserver( this , callfuncO_selector(HelloWorld::getMsg), "test" , nullptr); // 发布消息 postNotification this ->sendMsg(); return true ; } // 发布消息 void HelloWorld::sendMsg() { // 发布名称为"test"的消息 NotificationCenter::getInstance()->postNotification( "test" , nullptr); } // 消息回调函数,接收到的消息传递数据为sender void HelloWorld::getMsg(Ref* sender) { CCLOG( "getMsg in HelloWorld" ); } // |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
// void __NotificationCenter::addObserver(Ref *target, SEL_CallFuncO selector, const std::string& name, Ref *sender) { // target已经订阅了name这个消息 if ( this ->observerExisted(target, name, sender)) return ; // 为target主体订阅的name消息,创建一个观察者 NotificationObserver *observer = new NotificationObserver(target, selector, name, sender); if (!observer) return ; // 加入 _observers 数组 observer->autorelease(); _observers->addObject(observer); } // |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
// void __NotificationCenter::postNotification( const std::string& name, Ref *sender = nullptr) { __Array* ObserversCopy = __Array::createWithCapacity(_observers->count()); ObserversCopy->addObjectsFromArray(_observers); Ref* obj = nullptr; // 遍历观察者数组 CCARRAY_FOREACH(ObserversCopy, obj) { NotificationObserver* observer = static_cast <NotificationObserver*>(obj); if (!observer) continue ; // 是否订阅了名称为name的消息 if (observer->getName() == name && (observer->getSender() == sender || observer->getSender() == nullptr || sender == nullptr)) { // 执行observer对应的target主体所绑定的selector回调函数 observer->performSelector(sender); } } } // |
1
2
3
4
5
6
7
8
|
// // 是否订阅了名称为name的消息 if (observer->getName() == name && (observer->getSender() == sender || observer->getSender() == nullptr || sender == nullptr)) { // 执行observer对应的target主体所绑定的selector回调函数 observer->performSelector(sender); } // |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
// class Base : public Ref { public : void walk(Ref* sender) { CCLOG( "%s is walk" , data); } void run(Ref* sender) { CCLOG( "%s is run" , data); } // 订阅消息 void addObserver() { // 订阅 "walk" 和 "run" 消息 // 故意传递一个 data 数据 NotificationCenter::getInstance()->addObserver( this , callfuncO_selector(Base::walk), "walk" , (Ref*)data); NotificationCenter::getInstance()->addObserver( this , callfuncO_selector(Base::run), "run" , (Ref*)data); } public : char data[10]; // 类数据,表示类名 }; class A : public Base { public : A() { strcpy (data, "A" ); } // 数据为类名 "A" }; class B : public Base { public : B() { strcpy (data, "B" ); } // 数据为类名 "B" }; // |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
// bool HelloWorld::init() { if ( !Layer::init() ) return false ; // 创建A类和B类。 A* a = new A(); B* b = new B(); a->addObserver(); // A类 订阅消息 b->addObserver(); // B类 订阅消息 // 发布 "walk" 消息 NotificationCenter::getInstance()->postNotification( "walk" ); // 分割线 CCLOG( "--------------------------------------------------" ); // 发布 "run" 消息 // 故意传递一个数据 a类的data数据 NotificationCenter::getInstance()->postNotification( "run" , (Ref*)a->data); return true ; } // |