IMP methodForSelector EXC_BAD_ACCESS crash

0

I have received a couple of crash reports, and the only thing I can see in common is that they are both iPhone 5. I can't reproduce the crash on iPhone 5s or 6 so I I assumed it was a 64/32 bit issue. However the code also runs fine on an iPhone 4s running iOS 7.

The crash is happening on the last line here:

IMP imp = [self.delegate methodForSelector:aSelector];
id (*func)(id, SEL, id) = (void *)imp;
func(self.delegate, aSelector, self);

To be perfectly honest, I don't understand these 3 lines of code. I found them to overcome a compiler warning may cause a leak because its selector is unknown when using [self.delegate performSelector:aSelector withObject:self]; When I push an update using performSelector it doesn't crash.

I need to pass an argument of self along with the selector which is why I used IMP and added self as the third argument which is how I read it should be done.

The actual crash log doesn't reveal much:

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)

Is there anyone that can shed some light on this?

Thanks

EDIT ---- I am now also seeing crashes on iPad 3 (iOS 8.1.2) & iPhone 5 (iOS 8.1). Yet still can't reproduce it myself, I also tried an iPod (iOS 8.1) and iPad mini retina (iOS 8.1.3). This is really bugging me (Pun intended).

EDIT 2 ---- I've added some Crashlytics logs to log self.delegate self imp & func and they all appear to be fine! So why does the very next line crash?

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
ios
objective-c
iphone
crash
exc-bad-access
asked on Stack Overflow Feb 3, 2015 by Darren • edited Feb 3, 2015 by Darren

1 Answer

3

I had the same problem, working code 6 months ago now crashes, fixed it with those changes :

//old code

 IMP imp = [_target methodForSelector:_action];
 id (*func)(id, SEL, id) = (void *)imp;
 func(_target, _action, params);

//replaced by

 void (*imp)(id, SEL, id) = (void(*)(id,SEL,id))[_target methodForSelector:_action];
 if( imp ) imp(_target, _action, params);
answered on Stack Overflow Sep 10, 2015 by Yann Bouschet

User contributions licensed under CC BY-SA 3.0