被逮到一个初始状态考虑不周的Bug
这个bug发生在一个纯脚本的TreeView控件上面,其异常表现为:当使用键盘Up&Down键移动TreeView上面被选中的Item时,IE报告currentNode为空的脚本错误。关于这个功能的详细设计,可以参看本文,示例效果为:
上图中的node就是程序中的currentNode,Up&Down操作就是根据这个node来进行计算并移动的。在TreeView控件中,为了处理TreeView节点被多选时找到一个确切的currentNode,在每次选择操作时,我在TreeView实例的全局cache中纪录了一个叫m_LastSelected的值,保存最后一次选择动作中的第一个节点。如果是单选就是被选中的节点本身,如果是多选,就是多选时第一个被选中的节点。
{
// . . .
if ( innerCache.m_Selecteds.m_Count == 0 )
{
return;
}
var currentNode = innerCache.m_LastSelected;
// . . .
}
Review上面这段代码,取currentNode的地方似乎是已经做了安全检查,可是怎么还是出错了呢?其实除了本身程序有错,上面这个校验代码也是不对的,我检查的是m_Selecteds这个集合里面有没有东西,然后却是用m_LastSelected赋的值,这之间就可能出现m_Selecteds和m_LastSelected不同步的问题。结果确实是m_Selecteds和m_LastSelected之间的关联出了问题!看下面的代码:
{
// . . .
if ( (!evt.shiftKey && !evt.ctrlKey) || !objNode.Attributes('IsMultipleSelected') )
{
innerCache.UnselectAll();
objNode.SetSelected(true);
innerCache.m_LastSelected = objNode;
}
// . . .
};
由于m_LastSelected和node的选取顺序有关系,它被实现在了鼠标选择TreeView节点的逻辑中,即每次节点被鼠标点选就会更新m_LastSelected的值。
这个逻辑似乎是没有什么问题,反正只要是选择了TreeView上的节点,就会有m_LastSelected的存在,我们也就会得到Up&Down操作的计步节点currentNode。可是就是这里漏掉了一个情况的考虑,如果被选中节点是在initialize我们的TreeView时,由调用代码来设置给节点的(示例如下)。那么由于实现时的疏忽,就出现了m_Selecteds非空,而m_LastSelected为空的情况。
var node = TreeNode('default node');
tree.Add(node);
tree.Show(/* treeview container element*/);
node.SetSelected(true);
SetSelected(isSelected)方法实现如下:
{
var innerCache = this.m_Tree.m_InnerCache;
if ( isSelected )
{
if ( !innerCache.m_Selecteds.Contains(this) )
{
innerCache.m_Selecteds.Add(this);
}
}
else
{
innerCache.m_Selecteds.Remove(this);
}
if ( this.m_Selected != isSelected )
{
this.m_Selected = isSelected;
if ( this.e_SelectedChanged )
{
this.e_SelectedChanged.Execute(isSelected);
}
}
this.ApplyUIChange();
};
问题就是这里了,调用SetSelected选中了节点后,m_Selecteds这个集合是更新了,可是却没有设置m_LastSelected(由于Last Selected Node的定义,本身是不该在这里设置),这样就造成了m_Selecteds和m_LastSelected的不同步。从而出现了开始说到的,进行Up&Down操作结果出现currentNode为空的错误。
这个bug如果是Review代码可能细心能找出来,可是直接被QA通过黑合测试给提了出来,确实是相当相当不容易的。因为刚初始化好的TreeView是没有获得焦点的,这时不管怎么按Up&Down键都不会有反映,也就看起来并没有什么错误。如果使用鼠标点击一下TreeView内的任何区域,让其获得焦点,那么至少都会选中一个TreeNode,这样一来m_LastSelected也就有值了。那么这个如此隐蔽的bug是怎么发现的呢?这需要在页面载入并在TreeView生成后,立即使用Tab键把焦点移到TreeView的container元素上,这时候按Up&Down键,如果TreeView上面有初始花时被SetSelected(isSelected)选中的节点,那么就出错了。
本文转自博客园鸟食轩的博客,原文链接:http://www.cnblogs.com/birdshome/,如需转载请自行联系原博主。
被逮到一个初始状态考虑不周的Bug相关推荐
- 一个历时五天的 Bug
一个程序员在没有成长成为架构师之前,几乎都要跟 Bug为伴,程序员有很多时间都是花在了查找各种 Bug上. 我印象深刻的一个Bug, 是一个服务器网络框架无锁队列的 Bug .那个 Bug 连续查找了 ...
- 记录一个海思TOE的BUG
原始引用地址: 记录一个海思TOE的BUG time: 2020.5.3 17:57 发现的过程 最近在做onvif开发时,有x86的验证的功能没有问题,移动到海思Hi3536上简单运行貌视也很正 ...
- 一个有关fstream类的bug
一个有关fstream类的bug 近日写程序需要读出文件,对读出的内容作些修改,再写回到文件中. 突然发现一个莫名其妙的问题,写回去的时候居然在文件末尾增加了几个字 符.感到很不可思议.具体代码如下: ...
- 一个历时五天的 Bug,是如何被灭的?
作者 | 大飞 本文经授权转大飞码字 一个程序员在没有成长成为架构师之前,几乎都要跟 Bug为伴,程序员有很多时间都是花在了查找各种 Bug上. 我印象深刻的一个Bug, 是一个服务器网络框架无锁队列 ...
- 一个多线程示例程序的BUG修复
一个多线程示例程序的BUG修复 在<.NET 4.0面向对象编程漫谈 >的<应用篇>一书中,我介绍了一个使用"信号量(Semaphore) "同步对象模拟多 ...
- 软件测试一个星期没找到bug,一个月都没有发现bug,怎么办?
昨天从51testing论坛看到一道题目,很有意思,如果是面试时突然提问,可能还真不太好回答. "给你一个软件,你测试了一个月都没有发现bug,这说明什么?你怎么办?" 当时看到这 ...
- CTO:再写if-else,逮着一个罚款1000!
点击上方 好好学java ,选择 星标 公众号重磅资讯,干货,第一时间送达 今日推荐:分享一套基于SpringBoot和Vue的企业级中后台开源项目,这个项目有点哇塞!个人原创100W +访问量博客: ...
- 逮到一个阿里 10 年老 测试开发,聊过之后收益良多...
老话说的好,这人呐,一单在某个领域鲜有敌手了,就会闲得蛋疼.前几天我在上班摸鱼刷CSDN的时候认识了一位阿里测试开发大佬,在阿里工作了10年,因为本人天赋比较高,平时工作也兢兢业业,现在企业内有一定的 ...
- 在知乎逮到一个腾讯10年老测试开发,聊过之后收益良多...
老话说的好,这人呐,一单在某个领域鲜有敌手了,就会闲得蛋疼.前几天我在上班摸鱼刷知乎的时候认识了一位腾讯测试开发大佬,在腾讯工作了10年,因为本人天赋比较高,平时工作也兢兢业业,现在企业内有一定的地位 ...
最新文章
- Spring MVC 相关资料整理
- HTML5学习笔记(十四):变量作用域
- The Power of Ten – Rules for Developing Safety Critical Code
- python3扫盲系列-(3)
- aws cognito_AWS Cognito的用户管理—(2/3)核心功能
- Thinking in java之前
- 配置设备作为DHCP 服务器(基于全局地址池)
- [转载]Qt之中文显示(QMessageBox、QLineEdit右键菜单等)
- VC++实现标准型计算器步骤及源码
- 【图像处理】【去模糊】图像去模糊之初探--Single Image Motion Deblurring
- 让系统“飞”起来 读懂电脑虚拟内存常遇问题
- 专业化分类服务,引领IDC行业发展新模式
- linux笔记:shell编程-正则表达式
- 学以致用深入浅出数字信号处理 pdf_数字阵列雷达:零中频接收机的优缺点
- Word转html实现在线预览
- Android App 安全登录认证解决方案
- 基于网易云音乐API的无线音箱
- 《TypeScript》入门与精通-.d.ts描述文件的使用和详解
- 数据链路层——MAC地址欺骗及泛洪
- 关于CORBA实现的介绍
热门文章
- 细聊分布式ID生成方法-2
- Java RSA加密(一)--BCD输出
- 学号程序编辑 c语言,C语言程序设计实习报告 行编辑器 学生管理系统
- c语言递归汉诺塔次数,c语言递归解决汉诺塔参数变化的疑惑
- insert sort java_java插入排序 Insert sort实例
- ios10发邮件服务器拒绝,IOS10用户拒绝网络权限后,如何引导开启?
- Android让控件位于底部
- python用一行代码计算1~100的和(用reduce()和sum()内置函数实现)
- diy无感无刷电机霍尔安装_霍尔传感器常见的有那几个类别
- cfilefind 能找ftp 服务器上的文件夹吗?,将ftp目录映射为本地盘符