4

我在 iOS 中使用一些 JSON 解析,我想添加一个微调器,这很有效,但我无法停止微调器,我想了解原因。

[spinner stopAnimating]在异步块中被调用,我相信这就是问题所在,可能是因为我无法在块中的微调器上调用该方法?我已经记录了微调器 obj,输出为:

<UIActivityIndicatorView: 0x76905f0; frame = (150 230; 20 20); layer = <CALayer: 0x768ffb0>>

也许有人可以让我理解如何在 Objective-c 中处理这种异步方法。我是一个绝对的初学者。

编码:

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


}
4

3 回答 3

8

永远永远永远(永远!)在后台线程上与界面交谈。您想要的是跳回主线程-正如您正确怀疑的那样。这很容易:

[spinner startAnimating];
dispatch_async(kBgQueue, ^{
    NSData* data = [NSData dataWithContentsOfURL:
                    kLatestKivaLoansURL];
    // ... do other stuff in the background
    dispatch_async(dispatch_get_main_queue(), ^{
        [spinner stopAnimating];
    });
});

但是,您使用performSelectorOnMainThread:withObject:waitUntilDone:withwaitUntilDone:YES也是错误的(或者至少是一种非常难闻的气味),因为您不应该阻塞您的后台线程。只需在后台线程上调用一个方法(除非它触及界面),当结果返回时,它会返回。

于 2013-01-26T16:02:27.067 回答
1

在 stopAnimating 之后也调用方法 removeFromSuperview

    [spinner stopAnimating];
    [spinner removeFromSuperview];
于 2013-01-26T15:55:52.687 回答
0

UIKit 调用只能在主线程中进行。试试这个:

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

     });
});
于 2013-01-26T16:13:58.567 回答