Cocos2dx學習筆記38 plist的非同步載入
原文地址:http://cn.cocos2d-x.org/tutorial/show?id=556
Cocos2d-x中和Android,Windows都一樣,如果在主執行緒中處理一些耗時操作,那麼主執行緒就會出現阻塞現象,表現在介面上就是卡住,未響應等情況。為了避免這種情況的出現,我們需要在後臺開闢工作執行緒進行資料的處理,再採用訊息傳遞或者其他形式來通知主執行緒進行UI變化。最常見的情況就是遊戲進入前的loading。
1.圖片的非同步載入
在多執行緒和同步的第一篇介紹到使用pthread庫的時候,講到由於CCAutoreleasePool不是執行緒安全的,所以不能在工作執行緒中引入Cocos2d-x相關的API(其實並不是所有的API都不能使用)。但是Cocos2d-x顯然考慮到這個問題了,所以它本身就幫我們封裝好了一個API,避免了還要手動引入pthread庫的尷尬。
1 |
void
CCTextureCache::addImageAsync( const
char
*path, CCObject *target, SEL_CallFuncO selector)
|
2.plist的非同步載入
可是由於記憶體原因,大部分情況下圖片會被合成打包,同時帶入plist。這時候如何進行圖片的非同步載入呢?這個時候就需要對addImageAsync的原始碼進一步的探究了。
2.1.耗時的是什麼?
首先要理解的是耗時的動作是什麼,只有把耗時的工作真正抓出來丟到工作執行緒上,非同步載入才有意義。我們知道,圖片在記憶體中是以紋理的形式存在的,而圖片的載入,通俗來講也就是紋理的生成,這就是耗時的原因。那CCTexureCache中addImage(同步載入)和addImageAysnc(非同步載入)分別做了什麼事?
(1)addImage
可以看出addImage使用同步的方式生成了紋理,也就是在主執行緒中進行了耗時的載入操作。
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 |
//...Cocos2d-x維護著一個全域性紋理,在判斷紋理是否已存在
if
(! texture)
{
do
{
//...判斷圖片格式
pImage
= new
CCImage();
CC_BREAK_IF(NULL
== pImage);
bool
bRet = pImage->initWithImageFile(fullpath.c_str(), eImageFormat);
CC_BREAK_IF(!bRet);
texture
= new
CCTexture2D(); //開闢紋理空間
if (
texture &&
texture->initWithImage(pImage)
) //使用CCImage初始化紋理
{
#if
CC_ENABLE_CACHE_TEXTURE_DATA
//
cache the texture file name
VolatileTexture::addImageTexture(texture,
fullpath.c_str(), eImageFormat);
#endif
m_pTextures->setObject(texture,
pathKey.c_str());
texture->release();
}
|