나는 두 가지 충돌 보고서를 받았는데, 내가 볼 수있는 유일한 것은 그들이 모두 iPhone 5입니다. iPhone 5s 또는 6에서 충돌을 재현 할 수 없기 때문에 나는 그것을 가정했습니다. 64/32 비트 문제. 그러나 코드는 충돌 여기 마지막 줄에 무슨 일이 일어나고IMP methodForSelector EXC_BAD_ACCESS 충돌
아이폰 OS 7을 실행 아이폰 4S에 잘 실행 :
IMP imp = [self.delegate methodForSelector:aSelector];
id (*func)(id, SEL, id) = (void *)imp;
func(self.delegate, aSelector, self);
완벽하게 정직하기를, 나는 이러한 코드 3 줄을 이해하지 못하는 . 컴파일러 경고를 사용하여 컴파일러를 극복 할 수있었습니다. [self.delegate performSelector:aSelector withObject:self];
performSelector
을 사용하여 업데이트를 푸시해도 충돌이 발생하지 않습니다.
나는 IMP
을 사용한 이유와 self
을 인수로 전달해야하며, 읽어야 할 방법은 세 번째 인수로 추가했습니다.
실제 충돌 로그는 많이 공개하지 않습니다이 되거 수있는 사람이
Crashed: com.apple.main-thread EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0x00000100 Thread : Crashed: com.apple.main-thread
0 libobjc.A.dylib 0x30ca26b8 objc_retain + 7
1 Timeout 0x0009e2a1 __50-[BaseOperation finishedSuccessfullyWithSelector:]_block_invoke_2 (BaseOperation.m:47)
2 libdispatch.dylib 0x311e87bb
_dispatch_call_block_and_release + 10
3 libdispatch.dylib 0x311efe8b _dispatch_after_timer_callback + 66
4 libdispatch.dylib 0x311e87a7 _dispatch_client_callout + 22
5 libdispatch.dylib 0x311f9253 _dispatch_source_latch_and_call + 626
6 libdispatch.dylib 0x311ea2ed _dispatch_source_invoke + 212
7 libdispatch.dylib 0x311ebe1f _dispatch_main_queue_callback_4CF + 330
8 CoreFoundation 0x234a39d1 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
9 CoreFoundation 0x234a20d1 __CFRunLoopRun + 1512
10 CoreFoundation 0x233f0211 CFRunLoopRunSpecific + 476
11 CoreFoundation 0x233f0023 CFRunLoopRunInMode + 106
12 GraphicsServices 0x2a7e90a9 GSEventRunModal + 136
13 UIKit 0x269fc1d1 UIApplicationMain + 1440
14 Timeout 0x000a265b main (main.m:14)
있습니까?
감사
편집 ---- 나는 이제 아이 패드 3 (아이폰 OS 8.1.2) & 아이폰 5 (아이폰 OS 8.1)에 충돌을보고하고 . 그래도 나 자신을 재현 할 수는 없지만 iPod (iOS 8.1)과 iPad mini 망막 (iOS 8.1.3)도 시도했습니다. 이것은 정말로 나를 괴롭 히고 있습니다 (Pun은 의도했습니다).
편집 2 ---- 나는 self.delegate
self
imp
& func
를 기록 할 몇 가지 Crashlytics 로그를 추가 한 그들은 모두 잘 될 것으로 보인다! 그럼 왜 바로 다음 라인이 추락합니까?
// 이전 코드
IMP imp = [_target methodForSelector:_action];
id (*func)(id, SEL, id) = (void *)imp;
func(_target, _action, params);
이
void (*imp)(id, SEL, id) = (void(*)(id,SEL,id))[_target methodForSelector:_action];
if(imp) imp(_target, _action, params);
로 대체 // :
0 | 00:01:33:665 | $ __50-[BaseOperation finishedSuccessfullyWithSelector:]_block_invoke_2 : connectComplete:
1 | 00:01:33:665 | $ delegate: <BaseMenuViewController: 0x17e5e780>
2 | 00:01:33:666 | $ self: <ConnectOperation_Virgin: 0x1902a490>{name = '(null)'}
3 | 00:01:33:667 | $ imp: 0xaa345
4 | 00:01:33:667 | $ func: 0xaa345