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