我正在玩iOS中的一些JSON解析,我想添加一个微调器,这很有效,但我无法阻止微调器,我想了解原因。
在异步块中调用 [spinner stopAnimating]
,我相信问题所在,也许是因为我无法在块中调整spinner上的方法?我记录了微调器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];
});
}
答案 0 :(得分: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:
与waitUntilDone:YES
一起使用也是错误的(或至少是一种非常难闻的气味),因为您不应该阻止后台线程。只需在后台线程上调用一个方法(除非它触及界面),当结果返回时,它会回来。
答案 1 :(得分:1)
在stopAnimating
之后也调用removeFromSuperview方法 [spinner stopAnimating];
[spinner removeFromSuperview];
答案 2 :(得分: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];
});
});