Corona中文站

强大、易学的跨平台(iOS/Android)开发框架。QQ群1:74390406(满) 群2:221929599

导航

五分钟学会Corona(二十九) - 内存管理改进
注意: 本文档的信息适用于Corona 2.0 SDK Beta 7(或更早版本)的开发者,开发技术对内存管理技术的倚赖,不再使用。尤其,如果你存在代码这样使用 object:removeSelf() or group:remove(),你需要确保它不再倚赖于display object生命周期过时的假设。


再Corona 2.0 SDK的Beta 8期间,当display object被从他们的父组中删除,他们将被转换为孤儿。这些孤儿display object将不会被垃圾回收,直到所有指向它们的lua引用都被剔除。也就是说,lua代码中不再可以被访问。然而,当如display object被CG时,那些display object渲染相关的资源,不会立即被CG。而是,corona只能定期搜集这些资源(最多256 enterFrame事件后),并且这个特定的处理只会发生在屏幕更新时。


在beta 8和之后版本,当一个display object被从显示列表中删除,你应该假设它将立即删除所有的资源。然而你不能插入哪个对象到display列表中。如果有任何外部对那个display object的lua引用,那些引用将指向一个普通的lua table(而非一个display object)。


这个 collectgarbage(opt [, arg]) API 已经被修改,是关于opt参数是如何被解释:

• "collect" 提供一个lua中完整的GC(象以前),通过随后释放属于可GC对象中所有的渲染相关的资源。

• "collectlua" 提供一个lua中完整的GC。它等价于旧的"collect" 行为。


下面的display object方法已经被修改:

object:removeSelf( )

group:remove( indexOrChild )

在beta 8以及之后的修改,被删除对象的渲染相关的资源立即被删除。object保留的,是一个纯lua table,携带所有非display object属性(元表被设置为nil,并且所有和display object相关的属性被移除)。这样,如果lua中仍然有引用到object,它们将简单被引用到一个普通的 lua table。

移植代码

如果你有代码使用了object:removeSelf() or group:remove() , 你需要确保它不再倚赖于display object生命周期过时的假设。这里有一个之前和后来的例子,以说明你该如何处理:

BEFORE:

local bkgd = display.newImage( "bkgd.png" )

bkgd.foo = "random property data"


bkgd:removeSelf()

print( bkgd.foo ) -- OKAY: display object behaves like table

bkgd:rotate( 90 ) -- OKAY: bkgd is still a display object


AFTER:

local bkgd = display.newImage( "bkgd.png" )

bkgd.foo = "random property data"


bkgd:removeSelf()

print( bkgd.foo ) -- OKAY: bkgd is now a plain table; table properties are preserved

bkgd:rotate( 90 ) -- BAD: bkgd is no longer a display object


另一个一般的情况是,是 如果你删除对象并重新再插入它们,例如一个开关按钮。这时候,我们推荐你倚赖 isVisible属性,而不是显式从屏幕中删除对象后重新插入到后面。

BEFORE:

parent = display.newGroup()

play = display.newImage( "play.png" )

play:removeSelf()

pause = display.newImage( "pause.png" )

pause:removeSelf()


if isPlaying then

parent:insert(play)

else

parent:insert(pause)

end


AFTER:

parent = display.newGroup()

play = display.newImage( "play.png" )

play.isVisible = false

pause = display.newImage( "pause.png" )

pause.isVisible = false

if isPlaying then

play.isVisible = true

else

play.isVisible = false

end
<< 五分钟学会Corona(二十八) - 模块和包五分钟学会Corona(三十) - Corona API 热身 >>

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最近发表

Powered By Z-Blog 1.8 Walle Build 100427 Copyright 2011-2015 BuildApp.Net. All Rights Reserved.