EXC_BAD_INSTRUCTION at performSelector

2019-09-02 18:28发布

问题:

I have this code:

dispatch_async(dispatch_get_main_queue(), ^(void) 
{ 
    SEL selector = @selector(callback:);
    [self.delegate performSelector:selector withObject:self];
});

Both self.delegate and self is not nil.

I am getting EXC_BAD_INSTRUCTION at the performSelector line.

Any idea?

回答1:

Try using the selector directly, and make surecallback: is a valid method of self.delegate:

dispatch_async(dispatch_get_main_queue(), ^(void) 
{ 
    [self.delegate performSelector:@selector(callback:) withObject:self];
});

Another debugging tip is to set NSZombieEnabled, MallocStackLogging, and guard malloc in the debugger. Then, when your App crashes, type this in the gdb console:

(gdb) info malloc-history 0x543216

Replace 0x543216 with the address of the object that caused the crash, and you will get a much more useful stack trace and it should help you pinpoint the exact line in your code that is causing the problem.

See this article for more detailed instructions.



回答2:

self.delegate might have been deallocated. The pointer will only be nil if you cleared it yourself, or it is a weak reference under ARC. Try running with the "Enable Zombie Objects" option turned on.

To do this, edit your current scheme be clicking on the scheme's name in the toolbar (e.g. "MyApp"), then select "Edit Scheme…". Click on the "Run MyApp" item on the source list on the left, then select the "Diagnostics" tab, and turn on the "Enable Zombie Objects" checkbox.



回答3:

I had the issue in Xcode 9 debugging calls to UI from outside Main Thread. I was simply trying to run blocking code from main thread.. while already on main thread!

Solution was to use this method (of course declaring as __block) all variables I needed to modify from the main thread (in my case just getting UIView width).

Of course if you need something async, just change dispatch_sync to dispatch_async

`
+ (void)runOnMainSafelyBlocking:(void(^)(void))block;
{
    if ([NSThread isMainThread])
    {
        block();
    }
    else
    {
        dispatch_sync(dispatch_get_main_queue(), block);
    }
}
`


标签: ios xcode