逻辑错误
  这个是思维方式的问题,但是也是问题严重的。一旦发生,很难查找。人总是难怀疑自己的思维方式。比如死循环的问题,严重的是函数间的循环引用,还有多线程的问题。 但是庆幸的是绝大多数的BUG都是由于知识储备不足和粗心大意造成的。所以合理性假设的第二条:
  首先怀疑基础性的原因,比如自己知识储备和粗心大意等人为因素,通过这些原因查找具体的问题。之后再去怀疑难处理的逻辑错误。 有了上面的合理性怀疑的一些基本策略,也不能缺少一些基本的素材啊。是常见的Crash原因,后我们还是得落地到这些具体的原因或者代码上,却找与BUG的因果性联系。
  1、访问了一个已经被释放的对象,比如:NSObject * aObj = [[NSObject alloc] init]; [aObj release]; NSLog(@”%@”, aObj);
  2、访问数组类对象越界或插入了空对象
  3、访问了不存在的方法
  4、字节对齐,(类型转换错误)
  5、堆栈溢出
  6、多线程并发操作
  7、Repeating NSTimer
  合理性假设第三条:尽可能的查找有可能性的具体原因。
  因果性分析
  首先必须先说明的是,我们要找的是“因果性”而不是“相关性“。这是两个极度被混淆的概念。而且,很多时候我们错误的把相关性当成了因果性。比如,在解决一个多线程问题的时候,发现了一个数据混乱的问题,但是百思不得其解。终于,有你意外的给某个对象加了个锁,数据正常了。然后你说这个问题是这个对象没有枷锁导致的。
  但是,根据上述你的分析,只能够得出该对象枷锁与否与数据异常有关系,而不能得出是数据异常的原因。因为你没能证明对象加锁是数据异常的充分必要条件,而只是使用了一个单因变量实验,变量是枷锁状态,取值x=[0,1],x为整形。然后实验结果是枷锁与否与数据异常呈现正相关性。
  相关性:在概率论和统计学中,相关(Correlation,或称相关系数或关联系数),显示两个随机变量之间线性关系的强度和方向。在统计学中,相关的意义是用来衡量两个变量相对于其相互独立的距离。在这个广义的定义下,有许多根据数据特点而定义的用来衡量数据相关的系数。
  因果性:因果是一个事件(即“因”)和第二个事件(即“果”)之间的关系,其中后一事件被认为是前一事件的结果。 错误的把相关性等价于因果性。不止是程序员,几乎所有人常见的逻辑错误。为了加深认识,可以看一下这篇小科普:相关性 ≠ 因果性。
  因果性分析的首要问题是,别被自己的逻辑错误欺骗,正确的分辨出相关性和因果性之间的区别。不要把相关性等价于因果性。
  之后便是因果性分析的内容了,之前一直反复说,因果性分析的目的是确定特定原因是BUG发生的充分必要条件。那么确定这个事情,需要两步:
  1、充分性证明
  2、必要性证明
  关于充分性证明,这个基本上是正常的逻辑推理。基本思路是,能够还原出BUG出现的路径,从原因到BUG发生处的代码,走了怎样的函数调用和控制逻辑。确定了这个基本上能够证明充分性。一般情况下根据Crash的堆栈信息能够,非常直接的证明充分性。
  关于必要性证明,这个比较困难了。充分性和必要性的定义如下:当命题“若A则B”为真时,A称为B的充分条件,B称为A的必要条件。那么必要性是,BUG能够作为导致BUG的原因的原因。这个说法比较拗口。换种说法,是你得确认这个BUG能够解释原因,这个BUG是而且只是这个原因造成的。
  只有证明了充分必要性,才能算是真正找到了BUG的原因。