注意: 本文档的信息适用于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