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

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 对象被删除掉。



view source
print ?
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

你可能感兴趣的:(cocos2dx CCHttpRequest里面的内存引用计数的故事)