├── .gitignore ├── README.md └── UILoader.ts /.gitignore: -------------------------------------------------------------------------------- 1 | #///////////////////////////////////////////////////////////////////////////// 2 | # Fireball Projects 3 | #///////////////////////////////////////////////////////////////////////////// 4 | 5 | library/ 6 | temp/ 7 | local/ 8 | build/ 9 | 10 | #///////////////////////////////////////////////////////////////////////////// 11 | # Logs and databases 12 | #///////////////////////////////////////////////////////////////////////////// 13 | 14 | *.log 15 | *.sql 16 | *.sqlite 17 | 18 | #///////////////////////////////////////////////////////////////////////////// 19 | # files for debugger 20 | #///////////////////////////////////////////////////////////////////////////// 21 | 22 | *.sln 23 | *.csproj 24 | *.pidb 25 | *.unityproj 26 | *.suo 27 | 28 | #///////////////////////////////////////////////////////////////////////////// 29 | # OS generated files 30 | #///////////////////////////////////////////////////////////////////////////// 31 | 32 | .DS_Store 33 | ehthumbs.db 34 | Thumbs.db 35 | 36 | #///////////////////////////////////////////////////////////////////////////// 37 | # exvim files 38 | #///////////////////////////////////////////////////////////////////////////// 39 | 40 | *UnityVS.meta 41 | *.err 42 | *.err.meta 43 | *.exvim 44 | *.exvim.meta 45 | *.vimentry 46 | *.vimentry.meta 47 | *.vimproject 48 | *.vimproject.meta 49 | .vimfiles.*/ 50 | .exvim.*/ 51 | quick_gen_project_*_autogen.bat 52 | quick_gen_project_*_autogen.bat.meta 53 | quick_gen_project_*_autogen.sh 54 | quick_gen_project_*_autogen.sh.meta 55 | .exvim.app 56 | 57 | #///////////////////////////////////////////////////////////////////////////// 58 | # webstorm files 59 | #///////////////////////////////////////////////////////////////////////////// 60 | 61 | .idea/ 62 | 63 | #////////////////////////// 64 | # VS Code 65 | #////////////////////////// 66 | 67 | .vscode/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # UILoader(资源加载和资源释放) TS库 2.x 版本(2.0.6 版本) 3 | 4 | ## 加载资源 5 | 6 | ```typescript 7 | void loadRes(url: string, type: typeof cc.Asset, callback: Function): void 8 | 9 | void loadResArr(paths: Array, callfun: Function): void; 10 | 11 | void loadAudioClip(path: string, callfun: Function): void; 12 | ``` 13 | 14 | --- 15 | 16 | ## 加载静态资源 17 | 18 | ```typescript 19 | void loadStaticRes(url: string, type: typeof cc.Asset, tag: string, callback: Function): void; 20 | 21 | void loadStaticResArr(paths: Array, tag: string, callfun: Function): void 22 | 23 | ``` 24 | 25 | --- 26 | 27 | ## 加载静态资源,可对其进行引用计数 28 | 29 | ```typescript 30 | void loadSpriteFrame(path: string, callfun: Function, retainRes: boolean = false) 31 | 32 | void loadSpriteFrames(paths: Array, callfun: Function, retainRes: boolean = false); 33 | 34 | ``` 35 | 36 | --- 37 | 38 | ## 对节点进行引用计数加一 39 | 40 | ```typescript 41 | void retainNodeRes(node: cc.Node): void; 42 | 43 | void releaseNodeRes(node: cc.Node): void; 44 | ``` 45 | 46 | --- 47 | 48 | ## 对节点进行引用计数减一 49 | 50 | ```typescript 51 | 52 | void releaseNodeRes(node: cc.Node): void; 53 | ``` 54 | 55 | --- 56 | 57 | ## 释放静态资源 58 | 59 | ```typescript 60 | void releaseStaticRes(tag: string): void; 61 | ``` 62 | 63 | --- 64 | 65 | ## 引用计数加一 66 | 67 | ```typescript 68 | void retatinRes(res: string): void; 69 | 70 | void releaseMusicRes(res: string): void; 71 | 72 | void retainArrayRes(res: string[]): void; 73 | ``` 74 | 75 | --- 76 | 77 | ## 引用计数减一 78 | 79 | ```typescript 80 | 81 | void releaseRes(res: string): void; 82 | 83 | void releaseArrayRes(res: string[]): void; 84 | ``` 85 | 86 | --- 87 | 88 | ## 更新Sprite 组件 和 Button 组件纹理 89 | 90 | ```typescript 91 | void updateSpriteTexture(target: cc.Node, spriteFrame: cc.SpriteFrame): void; 92 | 93 | void updateButtonTexture(target: cc.Node, normalSprite?: cc.SpriteFrame, pressedSprite?: cc.SpriteFrame, hoverSprite?: cc.SpriteFrame, disabledSprite?: cc.SpriteFrame): void; 94 | ``` 95 | 96 | --- 97 | 98 | ## 获取缓存资源的数量 99 | 100 | ```typescript 101 | void getCacheCount(): number; 102 | ``` 103 | 104 | --- 105 | 106 | ## 回收资源 107 | 108 | ```typescript 109 | void gc(): void; 110 | ``` 111 | -------------------------------------------------------------------------------- /UILoader.ts: -------------------------------------------------------------------------------- 1 | 2 | export default class UILoader { 3 | static singleInstance: UILoader = null; 4 | static getInstance(): UILoader { 5 | if (UILoader.singleInstance == null) { 6 | UILoader.singleInstance = new UILoader(); 7 | } 8 | return UILoader.singleInstance; 9 | } 10 | 11 | // 资源加载到内存不会进行引用计数管理 12 | loadRes(url: string, type: typeof cc.Asset, callback): void { 13 | if (!url || !type || !callback) { 14 | cc.log("参数错误"); 15 | return; 16 | } 17 | 18 | cc.loader.loadRes(url, type, (err, asset) => { 19 | if (err) { 20 | cc.log(`[资源加载] 错误 ${err}`); 21 | return; 22 | } 23 | callback(asset); 24 | }); 25 | } 26 | 27 | loadResArr(paths: Array, callfun: Function) { 28 | cc.loader.loadResArray(paths, function(err, assets){ 29 | if (err) { 30 | cc.log(err); 31 | return; 32 | } 33 | callfun(assets); 34 | }.bind(this)); 35 | } 36 | 37 | 38 | loadStaticRes(url: string, type: typeof cc.Asset, tag: string, callback) { 39 | if (!url || !type || !callback) { 40 | cc.log("参数错误"); 41 | return; 42 | } 43 | cc.loader.loadRes(url, type, (err, asset) => { 44 | callback(asset); 45 | this._parseStaticRes(asset, tag); 46 | }); 47 | } 48 | 49 | loadStaticResArr(paths: Array, tag: string, callfun: Function) { 50 | if (!paths || !tag || !callfun) { 51 | cc.log("参数错误"); 52 | return; 53 | } 54 | 55 | cc.loader.loadResArray(paths, function(err, assets){ 56 | if (err) { 57 | cc.log(err); 58 | return; 59 | } 60 | callfun(assets); 61 | assets.forEach((asset) => { 62 | this._parseStaticRes(asset, tag); 63 | }); 64 | }.bind(this)); 65 | } 66 | 67 | 68 | 69 | loadAudioClip(path: string, callfun) { 70 | cc.loader.loadRes(path, cc.AudioClip, (err, audioclip) => { 71 | if (err) { 72 | cc.log(err); 73 | return; 74 | } 75 | callfun(audioclip); 76 | }); 77 | } 78 | 79 | loadSpriteFrame(path: string, callfun: Function, retainRes: boolean = false) { 80 | cc.loader.loadRes(path, cc.SpriteFrame, (err, spriteFrame) => { 81 | if (err) { 82 | cc.log(err); 83 | return; 84 | } 85 | if (retainRes) { 86 | this.retatinRes(spriteFrame._textureFilename); 87 | } 88 | callfun(spriteFrame); 89 | }); 90 | } 91 | 92 | 93 | loadSpriteFrames(paths: Array, callfun: Function, retainRes: boolean = false) { 94 | cc.loader.loadResArray(paths, cc.SpriteFrame, function(err, spriteFrames){ 95 | if (err) { 96 | cc.log(err); 97 | return; 98 | } 99 | if (retainRes) { 100 | spriteFrames.forEach((spriteFrame) => { 101 | this.retatinRes(spriteFrame._textureFilename); 102 | }); 103 | 104 | } 105 | callfun(spriteFrames); 106 | }.bind(this)); 107 | } 108 | 109 | 110 | releaseMusicRes(res: string): void { 111 | this.releaseRes(res); 112 | this.gc(); 113 | } 114 | 115 | 116 | 117 | releaseStaticRes(tag: string): void { 118 | var texturesInCache = cc.loader["_cache"]; 119 | var release_key = []; 120 | for (var asset in texturesInCache) { 121 | if (tag && texturesInCache[asset].uTag !== tag) { 122 | continue; 123 | } 124 | 125 | if (texturesInCache[asset].bk_count > 0 && texturesInCache[asset].uStatic) { 126 | // 移除 Static 标识, 127 | texturesInCache[asset].uStatic == null; 128 | delete texturesInCache[asset].uStatic; 129 | continue; 130 | } 131 | 132 | if (texturesInCache[asset].bk_count <= 0) { 133 | release_key.push(texturesInCache[asset].url); 134 | cc.log(`释放资源:${texturesInCache[asset].url}`); 135 | cc.loader.release(texturesInCache[asset].url); 136 | } 137 | } 138 | 139 | if (release_key.length > 0) { 140 | this._depthGC(release_key); 141 | } 142 | } 143 | 144 | 145 | 146 | 147 | getCacheCount() { 148 | return Object.keys(cc.loader["_cache"]).length; 149 | } 150 | 151 | 152 | 153 | retatinRes(res: string) { 154 | if (!cc.loader["_cache"][res]) { 155 | return; 156 | } 157 | 158 | if (!cc.loader["_cache"][res].bk_count) { 159 | cc.loader["_cache"][res].bk_count = 0; 160 | } 161 | cc.loader["_cache"][res].bk_count += 1; 162 | } 163 | 164 | retainArrayRes(res: string[]) { 165 | res.forEach((item) => { 166 | this.retatinRes(item); 167 | }); 168 | } 169 | 170 | retainNodeRes(node: cc.Node) { 171 | this._parserNodeRes(node, 1); 172 | } 173 | 174 | releaseNodeRes(node: cc.Node) { 175 | this._parserNodeRes(node, -1); 176 | } 177 | 178 | releaseRes(res: string) { 179 | if (!cc.loader["_cache"][res]) { 180 | return; 181 | } 182 | 183 | if (!cc.loader["_cache"][res].bk_count) { 184 | cc.loader["_cache"][res].bk_count = 0; 185 | } 186 | cc.loader["_cache"][res].bk_count -= 1; 187 | } 188 | 189 | releaseArrayRes(res: string[]) { 190 | res.forEach((item) => { 191 | this.releaseRes(item); 192 | }); 193 | } 194 | 195 | 196 | 197 | 198 | gc(){ 199 | var texturesInCache = cc.loader["_cache"]; 200 | var release_key = []; 201 | for (var asset in texturesInCache) { 202 | if (texturesInCache[asset].uStatic) { 203 | continue; 204 | } 205 | if (texturesInCache[asset].bk_count <= 0) { 206 | release_key.push(texturesInCache[asset].url); 207 | cc.log(`释放资源:${texturesInCache[asset].url}`); 208 | cc.loader.release(texturesInCache[asset].url); 209 | } 210 | } 211 | 212 | if (release_key.length > 0) { 213 | this._depthGC(release_key); 214 | } 215 | } 216 | 217 | 218 | updateSpriteTexture(target: cc.Node, spriteFrame: cc.SpriteFrame) { 219 | if (!target || !spriteFrame || !target.getComponent(cc.Sprite)) { 220 | return; 221 | } 222 | let sprite = target.getComponent(cc.Sprite); 223 | this._replaceTagetTexture(sprite, "spriteFrame", spriteFrame); 224 | this.gc(); 225 | } 226 | 227 | updateButtonTexture(target: cc.Node, normalSprite?: cc.SpriteFrame, pressedSprite?: cc.SpriteFrame, hoverSprite?: cc.SpriteFrame, disabledSprite?: cc.SpriteFrame) { 228 | if (!target || !normalSprite) { 229 | cc.log("参数错误") 230 | return; 231 | } 232 | 233 | if (!target.getComponent(cc.Button)) { 234 | cc.log("目标节点没有Button组件"); 235 | return; 236 | } 237 | 238 | let button = target.getComponent(cc.Button); 239 | if (normalSprite) { 240 | this._replaceTagetTexture(button, "normalSprite", normalSprite); 241 | } 242 | 243 | if (pressedSprite) { 244 | this._replaceTagetTexture(button, "pressedSprite", pressedSprite); 245 | } 246 | 247 | if (hoverSprite) { 248 | this._replaceTagetTexture(button, "hoverSprite", hoverSprite); 249 | } 250 | 251 | if (disabledSprite) { 252 | this._replaceTagetTexture(button, "disabledSprite", disabledSprite); 253 | } 254 | this.gc(); 255 | } 256 | 257 | _depthGC(strs: Array) { 258 | var texturesInCache = cc.loader["_cache"]; 259 | var release_json = []; 260 | for (var asset in texturesInCache) { 261 | if (texturesInCache[asset].dependKeys && texturesInCache[asset].dependKeys.length > 0) { 262 | var is_release = false; 263 | for (var i = 0; i < texturesInCache[asset].dependKeys.length; i++) { 264 | if (strs.indexOf(texturesInCache[asset].dependKeys[i]) !== -1) { 265 | is_release = true; 266 | } 267 | } 268 | if (is_release /*&& texturesInCache[asset].bk_count <= 0*/) { 269 | release_json.push(texturesInCache[asset].url); 270 | cc.log(`释放资源:${texturesInCache[asset].url}`); 271 | cc.loader.release(texturesInCache[asset].url); 272 | } 273 | } 274 | } 275 | 276 | if (release_json.length > 0) { 277 | this._depthGC(release_json); 278 | } 279 | } 280 | 281 | 282 | _parseStaticRes(item: typeof cc.Asset, tag: string) { 283 | if (item instanceof cc.Texture2D) { 284 | cc.loader["_cache"][item.url].uStatic = true; 285 | cc.loader["_cache"][item.url].uTag = tag; 286 | } else if (item instanceof cc.SpriteFrame) { 287 | cc.loader["_cache"][item["_textureFilename"]].uStatic = true; 288 | cc.loader["_cache"][item["_textureFilename"]].uTag = tag; 289 | } else if (item instanceof cc.Prefab) { 290 | this._parseStaticPrefab(item, tag); 291 | } else if (item instanceof cc.BitmapFont) { 292 | cc.loader["_cache"][item["spriteFrame"]._textureFilename].uStatic = true; 293 | cc.loader["_cache"][item["spriteFrame"]._textureFilename].uTag = tag; 294 | } else if (item instanceof cc.SpriteAtlas) { 295 | var keys = Object.keys(item["_spriteFrames"]) 296 | keys.forEach((key) => { 297 | cc.loader["_cache"][item["_spriteFrames"][key]._textureFilename].uStatic = true; 298 | cc.loader["_cache"][item["_spriteFrames"][key]._textureFilename].uTag = tag; 299 | }); 300 | } else if (item instanceof cc.AnimationClip) { 301 | cc.log('AnimationClip 资源加载未做处理'); 302 | } else if (item instanceof Object && item["name"]) { 303 | cc.log('Object 资源加载未做处理'); 304 | } 305 | } 306 | 307 | _parseStaticPrefab(node, tag: string) { 308 | var prefab = node; 309 | if (node.data) { 310 | prefab = node.data; 311 | } 312 | 313 | if (!(prefab instanceof cc.Scene)) { 314 | this._parseStaticNode(prefab, tag); 315 | } 316 | let children = prefab._children; 317 | children.forEach((child) => { 318 | this._parseStaticNode(child, tag); 319 | this._parseStaticPrefab(child, tag); 320 | }); 321 | } 322 | 323 | _retatinStaticRes(res: string, tag: string) { 324 | if (!cc.loader["_cache"][res]) { 325 | return; 326 | } 327 | 328 | if (!cc.loader["_cache"][res].bk_count) { 329 | cc.loader["_cache"][res].bk_count = 0; 330 | } 331 | cc.loader["_cache"][res].uStatic = true; 332 | cc.loader["_cache"][res].uTag = tag; 333 | } 334 | 335 | _parseStaticNode(node: cc.Node, tag: string) { 336 | // sprite 组件 337 | let sprite = node.getComponent(cc.Sprite); 338 | if (sprite && sprite.spriteFrame) { 339 | this._retatinStaticRes(sprite.spriteFrame["_textureFilename"], tag); 340 | } 341 | 342 | // button 组件 343 | let button = node.getComponent(cc.Button); 344 | if (button && button.normalSprite) { 345 | this._retatinStaticRes(button.normalSprite["_textureFilename"], tag); 346 | } 347 | if (button && button.pressedSprite) { 348 | this._retatinStaticRes(button.pressedSprite["_textureFilename"], tag); 349 | } 350 | if (button && button.hoverSprite) { 351 | this._retatinStaticRes(button.hoverSprite["_textureFilename"], tag); 352 | } 353 | if (button && button.disabledSprite) { 354 | this._retatinStaticRes(button.disabledSprite["_textureFilename"], tag); 355 | } 356 | 357 | // label 组件 358 | let label = node.getComponent(cc.Label); 359 | if (label && label.font && label.font instanceof cc.BitmapFont && label.font["spriteFrame"]) { 360 | this._retatinStaticRes(label.font["spriteFrame"]._textureFilename, tag); 361 | } 362 | 363 | // richText 组件 364 | let richText = node.getComponent(cc.RichText); 365 | if (richText && richText.imageAtlas) { 366 | let keys = Object.keys(richText.imageAtlas["_spriteFrames"]); 367 | if (keys.length > 0) { 368 | this._retatinStaticRes(richText.imageAtlas["_spriteFrames"][keys[0]]._textureFilename, tag); 369 | } 370 | } 371 | 372 | // particleSystem 组件 373 | let particleSystem = node.getComponent(cc.ParticleSystem); 374 | if (particleSystem && particleSystem["_texture"]) { 375 | this._retatinStaticRes(particleSystem["_texture"], tag); 376 | } 377 | 378 | // pageViewIndicator 组件 379 | let pageViewIndicator = node.getComponent(cc.PageViewIndicator); 380 | if (pageViewIndicator && pageViewIndicator.spriteFrame) { 381 | this._retatinStaticRes(pageViewIndicator.spriteFrame["_textureFilename"], tag); 382 | } 383 | 384 | // editBox 组件 385 | let editBox = node.getComponent(cc.EditBox); 386 | if (editBox && editBox.backgroundImage) { 387 | this._retatinStaticRes(editBox.backgroundImage["_textureFilename"], tag); 388 | } 389 | 390 | // Mask 391 | let mask = node.getComponent(cc.Mask); 392 | if (mask && mask.spriteFrame) { 393 | this._retatinStaticRes(mask.spriteFrame["_textureFilename"], tag); 394 | } 395 | } 396 | 397 | 398 | 399 | _replaceTagetTexture(target: any, attrName: string, newNormalSprite: cc.SpriteFrame) { 400 | if (target[attrName] === newNormalSprite) { 401 | return; 402 | } 403 | if (target[attrName]) { 404 | this.releaseRes(target[attrName]._textureFilename); 405 | } 406 | this.retatinRes(newNormalSprite["_textureFilename"]); 407 | target[attrName] = newNormalSprite; 408 | } 409 | 410 | _parserNodeRes(node: cc.Node, number: number) { 411 | let children = node.children; 412 | this._parserNodeComponentRes(node, number); 413 | children.forEach((child) => { 414 | this._parserNodeRes(child, number); 415 | }); 416 | } 417 | 418 | _parserNodeComponentRes(node: cc.Node, num: number) { 419 | this._parserComponentSprite(node, num); 420 | this._parserComponentButton(node, num); 421 | this._parserComponentLabel(node, num); 422 | this._parserComponentRichText(node, num); 423 | this._parserComponentParticleSystem(node, num); 424 | this._parserComponentPageViewIndicator(node, num); 425 | this._parserComponentEditBox(node, num); 426 | this._parserComponentMask(node, num); 427 | 428 | // TODO 释放其他组件附带的资源 429 | } 430 | 431 | _parserComponentSprite(node: cc.Node, num: number) { 432 | let sprite = node.getComponent(cc.Sprite); 433 | if (!sprite) { 434 | return; 435 | } 436 | if (num > 0) { 437 | this.retatinRes(sprite.spriteFrame["_textureFilename"]); 438 | return; 439 | } 440 | this.releaseRes(sprite.spriteFrame["_textureFilename"]); 441 | } 442 | 443 | _parserComponentButton(node: cc.Node, num: number) { 444 | let button = node.getComponent(cc.Button); 445 | if (!button) { 446 | return; 447 | } 448 | 449 | if (button.normalSprite) { 450 | if (num > 0) { 451 | this.retatinRes(button.normalSprite["_textureFilename"]); 452 | } else { 453 | this.releaseRes(button.normalSprite["_textureFilename"]); 454 | } 455 | } 456 | 457 | if (button.pressedSprite) { 458 | if (num > 0) { 459 | this.retatinRes(button.pressedSprite["_textureFilename"]); 460 | } else { 461 | this.releaseRes(button.pressedSprite["_textureFilename"]); 462 | } 463 | 464 | } 465 | 466 | if (button.hoverSprite) { 467 | if (num > 0) { 468 | this.retatinRes(button.hoverSprite["_textureFilename"]); 469 | } else { 470 | this.releaseRes(button.hoverSprite["_textureFilename"]); 471 | } 472 | } 473 | 474 | if (button.disabledSprite) { 475 | if (num > 0) { 476 | this.retatinRes(button.disabledSprite["_textureFilename"]); 477 | } else { 478 | this.releaseRes(button.disabledSprite["_textureFilename"]); 479 | } 480 | } 481 | } 482 | 483 | _parserComponentLabel(node: cc.Node, num: number) { 484 | let label = node.getComponent(cc.Label); 485 | if (!label || !label.font || !(label.font instanceof cc.BitmapFont) || !label.font["spriteFrame"]) { 486 | return; 487 | } 488 | 489 | if (num > 0) { 490 | this.retatinRes(label.font["spriteFrame"]["_textureFilename"]); 491 | return; 492 | } 493 | this.releaseRes(label.font["spriteFrame"]["_textureFilename"]); 494 | } 495 | 496 | _parserComponentRichText(node: cc.Node, num: number) { 497 | let richText = node.getComponent(cc.RichText); 498 | if (!richText || !richText.imageAtlas) { 499 | return; 500 | } 501 | 502 | let keys = Object.keys(richText.imageAtlas["_spriteFrames"]); 503 | if (keys.length <= 0) { 504 | return; 505 | } 506 | 507 | if (num > 0) { 508 | this.retatinRes(richText.imageAtlas["_spriteFrames"][keys[0]]["_textureFilename"]); 509 | return; 510 | } 511 | this.releaseRes(richText.imageAtlas["_spriteFrames"][keys[0]]["_textureFilename"]); 512 | } 513 | 514 | _parserComponentParticleSystem(node: cc.Node, num: number){ 515 | let particleSystem = node.getComponent(cc.ParticleSystem); 516 | if (!particleSystem || !particleSystem["_texture"]) { 517 | return; 518 | } 519 | 520 | if (num > 0) { 521 | this.retatinRes(particleSystem["_texture"]); 522 | return; 523 | } 524 | this.releaseRes(particleSystem["_texture"]); 525 | } 526 | 527 | _parserComponentPageViewIndicator(node: cc.Node, num: number) { 528 | let pageViewIndicator = node.getComponent(cc.PageViewIndicator); 529 | if (!pageViewIndicator || !pageViewIndicator.spriteFrame) { 530 | return; 531 | } 532 | 533 | if (num > 0) { 534 | this.retatinRes(pageViewIndicator.spriteFrame["_textureFilename"]); 535 | return; 536 | } 537 | this.releaseRes(pageViewIndicator.spriteFrame["_textureFilename"]); 538 | } 539 | 540 | _parserComponentEditBox(node: cc.Node, num: number) { 541 | let editBox = node.getComponent(cc.EditBox); 542 | if (!editBox || !editBox.backgroundImage) { 543 | return; 544 | } 545 | 546 | if (num > 0) { 547 | this.retatinRes(editBox.backgroundImage["_textureFilename"]); 548 | return; 549 | } 550 | this.releaseRes(editBox.backgroundImage["_textureFilename"]); 551 | } 552 | 553 | _parserComponentMask(node: cc.Node, num: number) { 554 | let mask = node.getComponent(cc.Mask); 555 | if (!mask || !mask.spriteFrame) { 556 | return; 557 | } 558 | 559 | if (num > 0) { 560 | this.retatinRes(mask.spriteFrame["_textureFilename"]); 561 | return; 562 | } 563 | this.releaseRes(mask.spriteFrame["_textureFilename"]); 564 | 565 | } 566 | } --------------------------------------------------------------------------------