No, anything that updates the UI has to be run on the main thread.
To fix your code, you will have to run in on the main thread. The easiest way would be to call the method directly, becasue IBActions are always invoked on the main thread:
[self gotoSecondController:@[@"hello there"]];
However, if you are not on the main thread already, you can make some code run on the main thread in a couple different ways. With blocks:
__block MyViewController *blockSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
[blockSelf gotoSecondController:@[@"hello there"]];
});
Or by using the method
[self performSelectorOnMainThread:@selector(gotoSecondController:) withObject:@[@"hello there"] waitUntilDone:NO];