问题的产生
项目是用ccs1.6做的UI,在某个需求中,需要把一个Sprite的SpriteFrame clone一份,去构造另一个
代码类似于
1 2 3 4 5 |
local sprite = cc.ui.UIImage.new("file1.png") sprite:pos(x,y):addTo(self) local sprite2 = cc.ui.UIImage.new(sprite:clone():getSpriteFrame()) sprite2:pos(x2,y2):addTo(self) |
这样并没有问题
但是如果sprite的SpriteFrame被set过一个新的,那sprite2得到的SpriteFrame,依然是老的
怎么回事?
查看源码,我们发现Node:clone()方法被重写了(在NodeEx.lua里)
1 2 3 4 5 6 7 8 9 |
function Node:clone() local cloneNode = self:createCloneInstance_() cloneNode:copyProperties_(self) cloneNode:copySpecialPeerVal_(self) cloneNode:copyCloneWidgetChildren_(self) return cloneNode end |
粗读一下代码,先克隆一个实例,然后克隆基础属性,最后递归把子节点也克隆了
那问题就应该出现在self:createCloneInstance_()上
查阅发现
1 2 3 |
function UIImage:createCloneInstance_() return UIImage.new(unpack(self.args_)) end |
好吧…直接用构造参数返回一个实例是什么鬼
既然出事了,就弄弄大
我们发现所有UI组件的createCloneInstance_方法都有这个问题
写一段比较简单的代码
1 2 3 4 5 6 |
local label = cc.ui.UILabel.new({text = "before"}) label:pos(x,y):addTo(self) label:setString("after") local label2 = label:clone() label2:pos(x2,y2):addTo(self) |
可以看到,屏幕上显示label显示after,label2显示before
如果不用UI组件呢?
我试了一下,直接使用Sprite和LabelTTF是没有问题的,那这个就可以定性为quick的bug了