很久很久以前

刚从业时,是做Java后端的
我们知道Integer是int的包装类,2个int类型的值是可以通过a == b来进行比较的
于是想当然以为Integer也是可以这么比较

一次事故就要开始

一个简单的充值验证,需要比较充值数额是否相等,用的Integer类
我们测试的时候用的是1块钱(10金币),比较金币拿了2个Integer来做==判断
10金币顺利通过测试,100金币也是,随之上线

事故的爆发

产品上线后,从后台查询发现,只有10金币和100金币的充值记录(但按经验看来是不合理的)
也有玩家陆续反应100块(1000金币)充值失败

原因

Java中<128的Integer取的是常量,内存地址是一样的,>=128时,则是重新开辟了一块内存
又因为==是比较内存地址用的,比较值相等应该用a.equals(b)

测试代码

输出

问题的产生

项目是用ccs1.6做的UI,在某个需求中,需要把一个Sprite的SpriteFrame clone一份,去构造另一个
代码类似于

这样并没有问题
但是如果sprite的SpriteFrame被set过一个新的,那sprite2得到的SpriteFrame,依然是老的

怎么回事?

查看源码,我们发现Node:clone()方法被重写了(在NodeEx.lua里)

粗读一下代码,先克隆一个实例,然后克隆基础属性,最后递归把子节点也克隆了

那问题就应该出现在self:createCloneInstance_()上
查阅发现

好吧…直接用构造参数返回一个实例是什么鬼

既然出事了,就弄弄大

我们发现所有UI组件的createCloneInstance_方法都有这个问题
写一段比较简单的代码

 
可以看到,屏幕上显示label显示after,label2显示before

如果不用UI组件呢?

我试了一下,直接使用Sprite和LabelTTF是没有问题的,那这个就可以定性为quick的bug了

BUG表现为,cocos2dx的工程下,在能输入文字的地方,点击iOS键盘上的"话筒"按钮,进行听写,此时APP直接崩溃

 

解决方法:

在CCDirectorCaller.mm文件里修改 doCaller方法

 

添加头文件

 

 

再次实验后问题消失

环境:cocos2dx 2.1rc0-x-2.1.4
ios7.0.6

https://github.com/boyu0/cocos2d-x/commit/c3778d8123537f0e991e98c2d89d3e577e3120f1