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
;
}
//
|