UIActivityIndicatorView won't stop

余生长醉 提交于 2019-12-07 07:23:46

问题


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];
  });


}

回答1:


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.




回答2:


also call the method removeFromSuperview after stopAnimating

    [spinner stopAnimating];
    [spinner removeFromSuperview];



回答3:


UIKit calls can only be made in the main thread. Try this:

dispatch_async(kBgQueue, ^{

     NSData* data = [NSData dataWithContentsOfURL:kLatestKivaLoansURL];
    [self performSelectorOnMainThread:@selector(fetchedData:)
                       withObject:data waitUntilDone:YES];
     NSLog(@"loans: %@", spinner);

     dispatch_async(dispatch_get_main_queue(), ^{

         [spinner stopAnimating];

     });
});


来源:https://stackoverflow.com/questions/14538560/uiactivityindicatorview-wont-stop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!