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?
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.
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.
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);
}
}
`