I'm playing with some JSON parsing in iOS and i wanted to add a spinner, this works wel but i can't stop the spinner and i would like to understand why.
[spinner stopAnimating]
is called in the async block and i believe thats where the problem is, maybe because i can't call the method on spinner in the block? i've logged the spinner obj and the output is:
<UIActivityIndicatorView: 0x76905f0; frame = (150 230; 20 20); layer = <CALayer: 0x768ffb0>>
Maybe somebody can make me understand how to deal with this async methods in objective-c. I'm a absolute beginner.
The code:
- (void)viewDidLoad{
[super viewDidLoad];
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
spinner.center = CGPointMake(160, 240);
[self.view addSubview:spinner];
[spinner startAnimating];
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL:
kLatestKivaLoansURL];
[self performSelectorOnMainThread:@selector(fetchedData:)
withObject:data waitUntilDone:YES];
NSLog(@"loans: %@", spinner);
[spinner stopAnimating];
});
}
Never never never (never!) talk to the interface on a background thread. What you want is to jump back into the main thread - as you rightly suspect. It's easy-peasy:
[spinner startAnimating];
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL:
kLatestKivaLoansURL];
// ... do other stuff in the background
dispatch_async(dispatch_get_main_queue(), ^{
[spinner stopAnimating];
});
});
However, your use of performSelectorOnMainThread:withObject:waitUntilDone:
with waitUntilDone:YES
is also wrong (or at least a very bad smell), since you should not be blocking on your background thread. Just call a method right here on the background thread (unless it touches the interface) and when the result comes back, it comes back.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With