What happed when we excute NSTimer invalidate?

微笑、不失礼 提交于 2021-01-29 09:30:43

问题


self.timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(timeCall:) userInfo:self.strong repeats:YES];
[self.timer invalidate];
NSLog(@"%p",[self.timer userInfo]);

Then app crashes because EXC_BAD_ACCESS.

Apple document says,

This method is the only way to remove a timer from an NSRunLoop object. The NSRunLoop object removes its strong reference to the timer, either just before the invalidate method returns or at some later point. If it was configured with target and user info objects, the receiver removes its strong references to those objects as well.

And Apple tells us not to use userInfo after a timer invalidate.But why?

The timer's refrence count is controlled by programmer,and also the userInfo(I tried use property as userInfo,instead of using constant string),the result is the same.

If we put a symbol breakpoint like -[NSTimer userinfo],we can get crash info like

CoreFoundation`-[__NSCFTimer userInfo]:
    0x7fff20384d32 <+0>:  pushq  %rbp
    0x7fff20384d33 <+1>:  movq   %rsp, %rbp
    0x7fff20384d36 <+4>:  pushq  %rbx
    0x7fff20384d37 <+5>:  subq   $0x38, %rsp
    0x7fff20384d3b <+9>:  movq   0x5fca7d6e(%rip), %rax    ; (void *)0x00007fff86d060e0: __stack_chk_guard
    0x7fff20384d42 <+16>: movq   (%rax), %rax
    0x7fff20384d45 <+19>: movq   %rax, -0x10(%rbp)
    0x7fff20384d49 <+23>: leaq   -0x38(%rbp), %rbx
    0x7fff20384d4d <+27>: movq   $0x0, (%rbx)
    0x7fff20384d54 <+34>: movq   %rbx, %rsi
    0x7fff20384d57 <+37>: callq  0x7fff203a6ff9            ; CFRunLoopTimerGetContext
    0x7fff20384d5c <+42>: movq   0x8(%rbx), %rax
->  0x7fff20384d60 <+46>: movq   0x18(%rax), %rax
    0x7fff20384d64 <+50>: movq   0x5fca7d45(%rip), %rcx    ; (void *)0x00007fff86d060e0: __stack_chk_guard
    0x7fff20384d6b <+57>: movq   (%rcx), %rcx
    0x7fff20384d6e <+60>: cmpq   -0x10(%rbp), %rcx
    0x7fff20384d72 <+64>: jne    0x7fff20384d7b            ; <+73>
    0x7fff20384d74 <+66>: addq   $0x38, %rsp
    0x7fff20384d78 <+70>: popq   %rbx
    0x7fff20384d79 <+71>: popq   %rbp
    0x7fff20384d7a <+72>: retq   
    0x7fff20384d7b <+73>: callq  0x7fff204c318e            ; symbol stub for: __stack_chk_fail

I know the relationship between NSRunloop and NSTimer,but what about this userinfo property?Maybe it's for archiving the readonly keyword,I guess.How can we look into the internel implementation of NSTimer or is there a way to explore?

来源:https://stackoverflow.com/questions/64662272/what-happed-when-we-excute-nstimer-invalidate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!