0

in my application i'm using a UIButton (myButton) wich i added via Storyboard.
So, when tapping the button an IBAction gets called:

-(IBAction)buttonAction:(UIButton*)sender{
    [myCustomClass doSomeCrazyStuff];
    [sender setEnabled:NO];
}

As you can see, i'm calling a method from myCustomClass ( myCustomClass is a REST-Client for my web-service).
The viewController the button lays in is delegate of myCustomClass.
There are two delegate methods implemented, one for success and one for error.

-(void)requestSucceeded{  
    /* If the request succeeded i want the button to be enabled again, and it's selected  
       state inverted */  
    NSLog(@"This gets called");
    [myButton setEnabled:YES];
    [myButton setSelected:!myButton.selected];
}

This works totally fine: i press the button, stuff is done on myCustomClass, request succeeds, button is set to inverted selected state.
But now for the other delegate method:

-(void)requestFailed{
    /* If the request failed i want the button to be enabled again, and it's selected  
       state stays the same */   
    NSLog(@"That gets called"); 
    [myButton setEnabled:YES];
}

If requestFailed gets called, the console prints That gets called as expected, but the button stays disabled... and i don't know why.
I tried other things in requestFailed like:

[myButton setHidden:YES];

Just to see if the reference to myButton is working...
And it is.

Probably i'm missing something right now, but i can't figure it out.
Thanks for your help.

EDIT:
I don't think requestFailed could be called from a different thread (as @gonji-dev mentioned), since both requestSucceeded and requestFailed are called from the same method.
In my doSomeCrazyStuff method i set up a completion block wich handles connection success and error. If an error occurred it gets handled in another class. If the connection succeeded i'm asking for HTTP status codes to decide wether requestFailed or requestSucceeded will be called.

  • Can you show us the code where you call requestFailed? Probably you're calling this from a different thread – Fabio Felici Jan 15 '16 at 11:36
  • I would set a breakpoint in `requestFailed`after `[myButton setEnabled:YES];` and check if the target still pointing to your controller. – Reinhard Männer Jan 15 '16 at 12:10
  • would not it be easier to distract the UI updates forcibly to the main-thread, rather than making assumptions of what _you don't think_, as debugging an issue is supposed not to be based on random assumptions; because if that is a background network request in your app, that must be in a background thread, and whatever they invoke it performed on that thread. – holex Jan 15 '16 at 12:10
  • So i tried to call request failed in dispatch_async(dispatch_get_main_queue(), ^{ }); and now the button gets enabled again... Thanks But i still don't know why `requestSucceeded` works and `requestFailed`did not work. Even though i don't know why, i'm happy it works ;) – Alexander Harl Jan 15 '16 at 13:22
  • @AlexanderHarl: did not see this comment until after I posted my anser. I can remove my response if you see fit. Additionally, a simple breakpoint where the log takes place would reveal the thread you are in. – SwiftArchitect Jan 16 '16 at 07:43

1 Answers1

0

Similar situation as in https://stackoverflow.com/a/31952060/218152.
Are you absolutely positive that you are invoking:

[myButton setEnabled:YES];

on the main thread?

The industry standard, when manipulating the UI in response to notifications or multithreaded environment is:

dispatch_async(dispatch_get_main_queue(), ^{
    // update UI
});
Community
  • 1
  • 1
SwiftArchitect
  • 43,382
  • 25
  • 129
  • 168
  • Thanks, i tried to call the delegate methods explicitly on the main thread and now it works for both methods. Don't know why it did not work for `requestFailed` before. But it must have had to do with it being on another thread. – Alexander Harl Jan 16 '16 at 15:18
  • Better safe than sorry: invoking UI outside of main thread is risky, and likely to crash on production. – SwiftArchitect Jan 17 '16 at 01:21