iOS.Crash.OniOS8.WhenCall[popToRootViewController]

系统iOS 8.x, ARC。

CrashCase:

在UIViewController中有一个类型为UIScrollView的实例变量scrollView,

点击UIViewController中的某个按钮时调用"[self.navigationController popViewControllerAnimated:NO];", 

在这之后该UIViewController的dealloc方法已被调用。在dealloc方法调用之后,scrollView其实还被系统View Tree

所持有,scrollView会访问其delegate,此时发生Crash。(UIScrollView的delegate)

在Debug时,

console会输出:"-[DSViewController respondsToSelector:]: message sent to deallocated instance 0x7ff3f6291160"

stack如图:

看第二frame: [UIScrollView _getDelegateZoomView], 执行停在line 18。

 1 UIKit`-[UIScrollView _getDelegateZoomView]:
 2 0x110dd48cd:  pushq  %rbp
 3 0x110dd48ce:  movq   %rsp, %rbp
 4 0x110dd48d1:  pushq  %r15
 5 0x110dd48d3:  pushq  %r14
 6 0x110dd48d5:  pushq  %rbx
 7 0x110dd48d6:  pushq  %rax
 8 0x110dd48d7:  movq   %rdi, %r14
 9 0x110dd48da:  movq   0xd344ef(%rip), %rax      ; UIScrollView._zoomView
10 0x110dd48e1:  movq   (%r14,%rax), %rbx
11 0x110dd48e5:  testq  %rbx, %rbx
12 0x110dd48e8:  jne    0x110dd497b               ; -[UIScrollView _getDelegateZoomView] + 174
13 0x110dd48ee:  movq   0xd344c3(%rip), %r15      ; UIScrollView._delegate
14 0x110dd48f5:  movq   (%r14,%r15), %rdi
15 0x110dd48f9:  movq   0xd08228(%rip), %rdx      ; "viewForZoomingInScrollView:"
16 0x110dd4900:  movq   0xd02df9(%rip), %rsi      ; "respondsToSelector:"
17 0x110dd4907:  callq  *0xac2783(%rip)           ; (void *)0x00000001124b8000: objc_msgSend
18 0x110dd490d:  xorl   %ebx, %ebx
19 0x110dd490f:  testb  %al, %al
20 0x110dd4911:  je     0x110dd497b               ; -[UIScrollView _getDelegateZoomView] + 174
21 0x110dd4913:  movq   (%r14,%r15), %rdi
22 0x110dd4917:  movq   0xd0820a(%rip), %rsi      ; "viewForZoomingInScrollView:"
23 0x110dd491e:  movq   %r14, %rdx
24 0x110dd4921:  callq  *0xac2769(%rip)           ; (void *)0x00000001124b8000: objc_msgSend
25 0x110dd4927:  movq   %rax, %rbx
26 0x110dd492a:  leaq   0xd6bcdb(%rip), %rax      ; _UIApplicationLinkedOnVersion
27 0x110dd4931:  movl   (%rax), %eax
28 0x110dd4933:  testl  %eax, %eax
29 0x110dd4935:  je     0x110dd4941               ; -[UIScrollView _getDelegateZoomView] + 116
30 0x110dd4937:  cmpl   $0x4ffff, %eax
31 0x110dd493c:  seta   %al
32 0x110dd493f:  jmp    0x110dd494b               ; -[UIScrollView _getDelegateZoomView] + 126
33 0x110dd4941:  movl   $0x50000, %edi
34 0x110dd4946:  callq  0x110d4b41f               ; _UIApplicationLinkedOnOrAfter
35 0x110dd494b:  testb  %al, %al
36 0x110dd494d:  je     0x110dd497b               ; -[UIScrollView _getDelegateZoomView] + 174
37 0x110dd494f:  cmpq   %r14, %rbx
38 0x110dd4952:  jne    0x110dd497b               ; -[UIScrollView _getDelegateZoomView] + 174
39 0x110dd4954:  movq   0xd2e5ad(%rip), %rdi      ; (void *)0x00000001109c2458: NSException
40 0x110dd495b:  movq   0xac1866(%rip), %rax      ; (void *)0x000000011098aa10: NSGenericException
41 0x110dd4962:  movq   (%rax), %rdx
42 0x110dd4965:  movq   0xd0487c(%rip), %rsi      ; "raise:format:"
43 0x110dd496c:  leaq   0xb06a3d(%rip), %rcx      ; @"The view returned from viewForZoomingInScrollView: must be a subview of the scroll view. It can not be the scroll view itself."
44 0x110dd4973:  xorl   %eax, %eax
45 0x110dd4975:  callq  *0xac2715(%rip)           ; (void *)0x00000001124b8000: objc_msgSend
46 0x110dd497b:  movq   %rbx, %rax
47 0x110dd497e:  addq   $0x8, %rsp
48 0x110dd4982:  popq   %rbx
49 0x110dd4983:  popq   %r14
50 0x110dd4985:  popq   %r15
51 0x110dd4987:  popq   %rbp
52 0x110dd4988:  retq   

解决方法:

DSViewController的dealloc中将添加: "scrollView.delegate = nil;"

Q1: 在iOS 7.x中没有Crash,这是不是iOS 8.x的系统bug?


Reference

1. UIScrollView internal consistency crash

http://stackoverflow.com/questions/26103756/uiscrollview-internal-consistency-crash

2. popToRootViewController crashes when tableView is still scrolling

http://stackoverflow.com/questions/26060727/poptorootviewcontroller-crashes-when-tableview-is-still-scrolling

原文地址:https://www.cnblogs.com/cwgk/p/4504228.html