今天遇到一个bug,让人劳神的不行,昨天看来半天没有头绪;今天终于找到症结所在,记录解决的过程,以做后鉴;
1、根据log,检查对应的代码的逻辑去查漏洞;
这是我第一个反应,通过代理逻辑,表面上没有漏洞;
2、复现之,看看新log比已有的log能否提供更多的信息;
问题是一个类在dealloc过程中导致的崩溃,所以,我写了一个自动重复调用的过程,这个过程就是不断的重复这个类dealloc,结果也没有复现出来,跟网速、操作的时机都有关系,所以复现的几率很小;
3、回到已有的日志上来,仔细查看每一条来分析,终于找到问题所在;
看似做了很多无用功,但是我觉得,没有前面的检查、复现来排除理论上的可能性,也不能最后通过log来确定问题所在;
上面描述的是解决的过程,下面说下解决的结果:
1、主角出场:
A类进行网络请求;
所有B类网络请求的管理类;
2、关系:
A类请求B类为自己获取数据,A类在dealloc中取消请求;
B类将A类存储到delegates(NSMutableArray)中,获取到结果后进行回调,回调完毕后在delegates中删除A;
B类中的取消请求操作也是从delegates中删除A;
3、矛盾(crash现象)
crash栈信息提示,在回调后,delegates删除A,然后是 A的dealloc,然后是
[__NSArrayM objectAtIndex:]: index 3 beyond bounds [0 .. 2]
关键是,之前的:
6 libobjc.A.dylib 0x37b1e175 _objc_rootRelease + 36 7 CoreFoundation 0x356c42e7 CFRelease + 94原来是这样的:
在B回调后,delegates(NSMutableArray)要删除A,会先将A的引用计数减一,如果此时A的引用计数为1,则A的引用计数会变为0,会调用dealloc,在dealloc中又会让delegates来删除A;整个过程通过测试都是在主线程,说明是串行的,这样,回调后的数组删除操作进行最后的删除一步(数组内部的删除对象)时,该对象已经被删除了;所以crash;