现在的位置: 首页 > 综合 > 正文

cocos2dx CCHttpRequest里面的内存引用计数的故事

2018年04月04日 ⁄ 综合 ⁄ 共 6407字 ⁄ 字号 评论关闭

CCHttpRequest 本身是一个CCObject 对象, 用于lua的create函数 默认会retain request对象一次,因此需要在lua的callback函数里面处理结束request之后,需要release对象否则会内存泄露。

实际的引用计数变化的过程如下:

new  引用计数 = 1

autorelease 引用计数先变成2 再变成1 , 将对象加入自动释放池子里面之后,对象引用计数会+1, 接着会调用对象的release方法,对象引用计数又减去1

retain 引用计数变成 2

start 开始http请求,对象加入schedule 的列表里面 引用计数+1 引用计数变成3

update 过程中,到下一个update循环的时候,对象的引用计数会减去1,因为自动释放池子release了这个对象,这时候引用计数变成2

http请求处理结束,update函数里面检测结束,取消schedule 更新,但是因为当前在函数体内,所以不会立即release掉request对象,而是等待本次回合结束的时候再release对象

http请求结束,在callback函数里面release 掉对象,引用计数-1  变成 1

在本次更新回合结束,schedule模块,将标记删除的对象的引用计数-1, 引用计数 = 0 对象被删除掉。



001 #include
"network/CCHttpRequest.h"
002 #include
"network/CCHttpRequest_impl.h"
003 #include
"cocos2d.h"
004  
005 #include
"CCLuaEngine.h"
006  
007 using namespace cocos2d;
008  
009 NS_CC_EXT_BEGIN
010  
011 CCHttpRequest*
CCHttpRequest::createWithUrl(CCHttpRequestDelegate* delegate,
012                                             const char*
url,
013                                             CCHttpRequestMethod
method,
014                                             bool isAutoReleaseOnFinish)
015 {
016     CCHttpRequest*
request = 
new CCHttpRequest(delegate,
url, method, isAutoReleaseOnFinish);
017     request->initHttpRequest();
018     request->autorelease();
019     if (isAutoReleaseOnFinish)
020     {
021         request->retain();
022     }
023     return request;
024 }
025  
026 CCHttpRequest*
CCHttpRequest::createWithUrlLua(
int nHandler, const char*
url, 
bool isGet)
027 {
028     CCHttpRequest*
request = 
new CCHttpRequest(NULL,
url, isGet?CCHttpRequestMethodGET:CCHttpRequestMethodPOST, 
true);
029     request->m_luaHandler
= nHandler;
030     request->initHttpRequest();
031     request->autorelease();
032     request->retain();
033     CCLog("request
count is? %d"
,
request->retainCount());
034     return request;
035 }
036  
037 bool CCHttpRequest::initHttpRequest(void)
038 {
039     m_request
new CCHttpRequest_impl(m_url.c_str(),
m_method);
040     return true;
041 }
042  
043 CCHttpRequest::~CCHttpRequest(void)
044 {
045     delete (CCHttpRequest_impl*)m_request;
046 }
047  
048 void CCHttpRequest::addRequestHeader(const char*
key, 
const char*
value)
049 {
050     if (key
&& value)
051     {
052         ((CCHttpRequest_impl*)m_request)->addRequestHeader(key,
value);
053     }
054 }
055  
056 void CCHttpRequest::addPostValue(const char*
key, 
const char*
value)
057 {
058     if (key
&& value)
059     {
060         ((CCHttpRequest_impl*)m_request)->addPostValue(key,
value);
061     }
062 }
063  
064 void CCHttpRequest::setPostData(const char*
data)
065 {
066     if (data)
067     {
068         ((CCHttpRequest_impl*)m_request)->setPostData(data);
069     }
070 }
071  
072 void CCHttpRequest::setTimeout(float timeout)
073 {
074     ((CCHttpRequest_impl*)m_request)->setTimeout(timeout);
075 }
076  
077 bool CCHttpRequest::getIsInProgress(void)
078 {
079     return ((CCHttpRequest_impl*)m_request)->getIsInProgress();
080 }
081  
082 void CCHttpRequest::start(bool isCached)
083 {
084     CCDirector::sharedDirector()->getScheduler()->unscheduleUpdateForTarget(this);
085     if (((CCHttpRequest_impl*)m_request)->start())
086     {
087         CCDirector::sharedDirector()->getScheduler()->scheduleUpdateForTarget(this,
0, 
false);
088     }
089 }
090  
091 void CCHttpRequest::cancel(void)
092 {
093     CCDirector::sharedDirector()->getScheduler()->unscheduleUpdateForTarget(this);
094     ((CCHttpRequest_impl*)m_request)->cancel();
095 }
096  
097 void CCHttpRequest::clearDelegatesAndCancel(void)
098 {
099     m_delegate
= NULL;
100     cancel();
101 }
102  
103 int CCHttpRequest::getResponseStatusCode(void)
{
104     return ((CCHttpRequest_impl*)m_request)->getResponseStatusCode();
105 }
106  
107 const char*
CCHttpRequest::getResponseString(
void)
108 {
109     return ((CCHttpRequest_impl*)m_request)->getResposeString().c_str();
110 }
111  
112 const void*
CCHttpRequest::getResponseData(
int*
dataLength)
113 {
114     return ((CCHttpRequest_impl*)m_request)->getResponseData();
115 }
116  
117 int CCHttpRequest::getResponseDataLength()
118 {
119     return ((CCHttpRequest_impl*)m_request)->getResponseDataLength();
120 }
121  
122 CCHttpRequestError 
CCHttpRequest::getErrorCode(
void)
123 {
124     return ((CCHttpRequest_impl*)m_request)->getErrorCode();
125 }
126  
127 const char*
CCHttpRequest::getErrorMessage(
void)
128 {
129     return ((CCHttpRequest_impl*)m_request)->getErrorMessage();
130 }
131  
132 void CCHttpRequest::update(float dt)
133 {
134     CCLog("update
Request state %d"
,
retainCount());
135     CCHttpRequest_impl*
request = (CCHttpRequest_impl*)m_request;
136     if (!request
|| !request->getIsInProgress())
137     {
138         CCDirector::sharedDirector()->getScheduler()->unscheduleUpdateForTarget(this);
139     }
140      
141     if (request->getIsCompleted())
142     {
143         if (m_delegate)
m_delegate->requestFinished(
this);
144          
145         if (m_luaHandler)
146         {
147             bool isSuc
= (request->getErrorCode()==CCHttpRequestErrorNone);
148             CCLuaEngine*
engine = CCLuaEngine::defaultEngine();
149  
150             engine->getLuaStack()->clean();
151             engine->getLuaStack()->pushBoolean(isSuc);
152             engine->getLuaStack()->executeFunctionByHandler(m_luaHandler,
1);
153             CCLog("afterHandler
retainCount %d"
,
retainCount());
154             /*
155             cocos2d::CCLuaValueDict
dict;
156             dict["name"]
= cocos2d::CCLuaValue::stringValue("completed");
157             dict["request"]
= cocos2d::CCLuaValue::ccobjectValue(this, "CCHttpRequest");
158             cocos2d::CCLuaEngine*
engine = cocos2d::CCLuaEngine::defaultEngine();
159             engine->cleanStack();
160             engine->pushCCLuaValueDict(dict);
161             engine->executeFunctionByHandler(m_luaHandler,
1);
162             */
163         }
164          
165     }
166     else if (request->getIsCancelled())
167     {
168         if (m_delegate)
m_delegate->requestFailed(
this);
169          
170         if (m_luaHandler)
171         {
172             CCLuaEngine*
engine = CCLuaEngine::defaultEngine();
173  
174             engine->getLuaStack()->clean();
175             engine->getLuaStack()->pushBoolean(false);
176             engine->getLuaStack()->executeFunctionByHandler(m_luaHandler,
1);
177             /*
178             cocos2d::CCLuaValueDict
dict;
179             dict["name"]
= cocos2d::CCLuaValue::stringValue("failed");
180             dict["request"]
= cocos2d::CCLuaValue::ccobjectValue(this, "CCHttpRequest");
181             cocos2d::CCLuaEngine*
engine = cocos2d::CCLuaEngine::defaultEngine();
182             engine->cleanStack();
183             engine->pushCCLuaValueDict(dict);
184             engine->executeFunctionByHandler(m_luaHandler,
1);
185             */
186         }
187     }
188 }
189  
190 NS_CC_EXT_END

抱歉!评论已关闭.