iOS7 Can't add self as subview 的崩溃
来源:互联网 发布:360数据流量控制 编辑:程序博客网 时间:2024/06/03 21:38
iOS7刚发布的时候,总是出现这个 Can't add self as subview 的崩溃,团队内部没出现过,但是外部用户的crash频频上报这个崩溃。
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Can't add self as subview'
这里有两个线索,一个是从崩溃堆栈中看到了崩溃的时间点:导航栏对内部的控制器做切换动画的时候崩溃。
另一个线索则是addSubView的参数不能是对象本身。一开始怀疑是addSubView传入self引起,于是用类似 [self addSubView:self] 的代码试了一下,的确是会崩溃的。
但是堆栈跟外部用户上报的不一样,排除 [self addSubView:self] 直接导致崩溃的可能性。
也就是说,不是我们工程调用了[self addSubView:self] 引起崩溃,
而是我们工程里面的某一些代码会导致UIKit内部执行 addSubView 的时候,传入了 self。
为什么说是我们的代码引起呢?因为崩溃的时候,页面总是停留在某几个特定的页面,这个后面会分析。
再看看第二个线索,即导航栏在做动画的时候出了问题。
以上,我们可以得出一个中间结论,即我们的代码,让导航栏在做动画的时候,执行了一次 [self addSubView:self]。
再说说崩溃集中的几个页面,用户上报的崩溃中,并不是总在一个页面崩溃,但是固定出现在特定的某几个页面。
着重看了log里面崩溃前每一个页面切换的时间,果然比较短,有些甚至少于0.5秒,少于导航栏push和pop动画的时间。
接着,用代码模拟一下快速切换的场景,比如0.3秒只能做两次push操作:
果然崩溃了,得到的堆栈跟文章开头的一模一样。
接着,检查崩溃上报的其他页面,发现这些页面都在特定的场景下会出现同时做push或者pop操作的情况。
于是,模拟各种短时间push和pop页面的场景,都会出现这样的崩溃。这时候几乎已经明确了就是动画被打断引起的。
原来,其实就是iOS5,6下的nested push 问题,只不过到iOS7上,这个问题的提前在做动画的时候崩溃了。
为了防止这种情况,我们在UINavigationController基类中加入防御,具体做法是在push,pop方法中设置一个标志位(animating=YES),在动画结束之后,再重置这个标志位,然后,用这个标志位判断push和pop操作是否能够执行。 比如,push这样实现:
其中有一个细节是,参与动画的两个控制器都需要设标志位。 结束动画的时候重置标志位,时机是在控制器的viewDidAppear和viewDidDisappear里面。
然后,这个crash就不见了。
异常描述和崩溃堆栈是这样的:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Can't add self as subview'
这里有两个线索,一个是从崩溃堆栈中看到了崩溃的时间点:导航栏对内部的控制器做切换动画的时候崩溃。
另一个线索则是addSubView的参数不能是对象本身。一开始怀疑是addSubView传入self引起,于是用类似 [self addSubView:self] 的代码试了一下,的确是会崩溃的。
但是堆栈跟外部用户上报的不一样,排除 [self addSubView:self] 直接导致崩溃的可能性。
也就是说,不是我们工程调用了[self addSubView:self] 引起崩溃,
而是我们工程里面的某一些代码会导致UIKit内部执行 addSubView 的时候,传入了 self。
为什么说是我们的代码引起呢?因为崩溃的时候,页面总是停留在某几个特定的页面,这个后面会分析。
再看看第二个线索,即导航栏在做动画的时候出了问题。
以上,我们可以得出一个中间结论,即我们的代码,让导航栏在做动画的时候,执行了一次 [self addSubView:self]。
再说说崩溃集中的几个页面,用户上报的崩溃中,并不是总在一个页面崩溃,但是固定出现在特定的某几个页面。
着重看了log里面崩溃前每一个页面切换的时间,果然比较短,有些甚至少于0.5秒,少于导航栏push和pop动画的时间。
接着,用代码模拟一下快速切换的场景,比如0.3秒只能做两次push操作:
果然崩溃了,得到的堆栈跟文章开头的一模一样。
接着,检查崩溃上报的其他页面,发现这些页面都在特定的场景下会出现同时做push或者pop操作的情况。
于是,模拟各种短时间push和pop页面的场景,都会出现这样的崩溃。这时候几乎已经明确了就是动画被打断引起的。
原来,其实就是iOS5,6下的nested push 问题,只不过到iOS7上,这个问题的提前在做动画的时候崩溃了。
为了防止这种情况,我们在UINavigationController基类中加入防御,具体做法是在push,pop方法中设置一个标志位(animating=YES),在动画结束之后,再重置这个标志位,然后,用这个标志位判断push和pop操作是否能够执行。 比如,push这样实现:
其中有一个细节是,参与动画的两个控制器都需要设标志位。 结束动画的时候重置标志位,时机是在控制器的viewDidAppear和viewDidDisappear里面。
然后,这个crash就不见了。
0 0
- iOS7 Can't add self as subview 的崩溃
- Can't add self as subview 的崩溃
- ios 'Can't add self as subview'崩溃日志详解
- 'Can't add self as subview'崩溃日志详解
- Can't add self as subview
- Can't add self as subview
- Can't add self as subview
- Can't add self as subview
- 错误:Can't add self as subview
- iOS app error - Can't add self as subview
- iOS bug解决 Can't add self as subview
- Can't add self as subview crash的出现的可能及解决方法
- phone - iOS app error - Can't add self as subview - Stack Overflow
- Can't find (or read) directory to add to classloader: ../../../contrib/extraction/lib (resolved as:
- ubuntu can't add add-apt-
- 关于ios7 scrollView的subView的frame不正确的调整
- can't get git rev, you should add git to system path or just input test value, such as 'testTinkerId
- you can’t add a second ‘$and’
- nginx负载均衡实战
- Source Insight 的使用
- mkisofs
- LCD驱动中pixclock的计算
- 一道面试题:操作系统常见面试题总结
- iOS7 Can't add self as subview 的崩溃
- HDU - 1394 - Minimum Inversion Number (线段树 - 单点更新,区间求和)
- JS小技巧
- visual studio如何自定义快捷键
- android---整形*浮点--相乘错误(浮点运算)----
- stdafx.h
- SSE技术简介
- list-style:none是什么意思
- HDU ACM 2181 哈密顿绕行世界问题->DFS(深度有限搜索)