在做客户端的时候需要开多线程,要用到子线程向主线程发送消息,但是CCNotificationCenter不是线程安全的,在网上看到《制作自己的捕鱼达人》一书中封装了一个MTNotificationQueue是线程安全的,我把它放到我的程序里之后 消息发送不了。 如下是我写的测试代码:
void HelloWorld::menuCallback(CCObject* pSender)
{
CCNotificationCenter::sharedNotificationCenter()->addObserver(this, callfuncO_selector(HelloWorld::gogogo), "GOGOGO", NULL);
pthread_t tid;
pthread_create(&tid, NULL, &next, NULL);
}
void* HelloWorld::next(void *)
{
CCLOG("next-----------");
MTNotificationQueue::sharedInstance()->postNotification("GOGOGO", NULL);
return NULL;
}
void HelloWorld::gogogo()
{
CCLOG("-----------------------gogogo");
}
//menuCallback是一个按钮的回调,点击按钮之后 注册标识为“GOGOGO”的消息,再创建一个新线程,在新线程里给主线程发送消息,主线程收到消息后调用next()方法
#ifndef __Demo__MTNotificationQueue__
#define __Demo__MTNotificationQueue__
#include "cocos2d.h"
#include
#include
using namespace cocos2d;
using namespace std;
class MTNotificationQueue : public CCObject {
public:
static MTNotificationQueue* sharedInstance();
void postNotifications(float in_fDeltaTime);
void postNotification(const char* in_pArrCharName, CCObject* in_pCcObj);
private:
MTNotificationQueue();
~MTNotificationQueue();
private:
static MTNotificationQueue* sm_pInstance;
class CGarbo {
public:
~CGarbo() {
if (MTNotificationQueue::sm_pInstance) {
delete MTNotificationQueue::sm_pInstance;
}
sm_pInstance = NULL;
}
};
static CGarbo sm_oCGarbo;
typedef struct {
string m_oStrName;
CCObject* m_pCcObj;
} NotificationArgs;
vector m_oVecNotifications;
};
#endif /* defined(__Demo__MTNotificationQueue__) */
//.m文件
#include "MTNotificationQueue.h"
pthread_mutex_t sharedNotificationQueueLock;
class LifeManager_PThreadMutex {
private:
pthread_mutex_t* m_pMutex;
public:
LifeManager_PThreadMutex(pthread_mutex_t* in_pMutex) : m_pMutex(in_pMutex) {
pthread_mutex_init(m_pMutex, NULL);
}
~LifeManager_PThreadMutex() {
pthread_mutex_destroy(m_pMutex);
}
}__LifeManager_sharedNotificationQueueLock(&sharedNotificationQueueLock);
class LifeCircleMutexLocker {
private:
pthread_mutex_t* m_pMutex;
public:
LifeCircleMutexLocker(pthread_mutex_t* in_pMutex) : m_pMutex(in_pMutex) {
pthread_mutex_lock(m_pMutex);
}
~LifeCircleMutexLocker() {
pthread_mutex_unlock(m_pMutex);
}
};
#define LifeCircleMutexLock(mutex) LifeCircleMutexLocker __locker__(mutex)
MTNotificationQueue* MTNotificationQueue::sm_pInstance = NULL;
MTNotificationQueue* MTNotificationQueue::sharedInstance() {
if (!sm_pInstance) {
sm_pInstance = new MTNotificationQueue();
}
return sm_pInstance;
}
MTNotificationQueue::MTNotificationQueue() {}
MTNotificationQueue::~MTNotificationQueue() {}
void MTNotificationQueue::postNotifications(float in_fDeltaTime) {
LifeCircleMutexLock(&sharedNotificationQueueLock);
CCNotificationCenter* t_pNotiCenter = CCNotificationCenter::sharedNotificationCenter();
for (uint16_t i = 0; i < m_oVecNotifications.size(); i ++) {
NotificationArgs& tmp_oNotiArgs = m_oVecNotifications*;
t_pNotiCenter->postNotification(tmp_oNotiArgs.m_oStrName.c_str(), tmp_oNotiArgs.m_pCcObj);
}
m_oVecNotifications.clear();
}
void MTNotificationQueue::postNotification(const char* in_pArrCharName, CCObject* in_pCcObj) {
LifeCircleMutexLock(&sharedNotificationQueueLock);
NotificationArgs t_oNotiArgs;
t_oNotiArgs.m_oStrName = in_pArrCharName;
if (in_pCcObj) {
t_oNotiArgs.m_pCcObj = in_pCcObj; // object->copy();
} else {
t_oNotiArgs.m_pCcObj = NULL;
}
m_oVecNotifications.push_back(t_oNotiArgs);
}