我有两个类,一个视图控制器和另一个(TwitterCrawler)对 Twitter API 执行网络请求。我在视图控制器加载时发出第一个网络请求,在用户按下按钮时发出第二个网络请求。
我希望在第一个请求完成时执行第二个请求,这意味着如果用户在第一个请求完成之前按下按钮,它会等待它结束然后执行第二个请求。
即使我将第一个请求放在我创建的队列中,dispatch_sync
我在用户按下按钮时调用的命令也会在队列清空之前调用。
这是我的代码:
//TwitterCrawler.m
-(void) getTwitterUsersInPosition: (Position*) position
{
dispatch_queue_async(twitterQueue, ^ {
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error){
if (granted) {
NSArray *accounts = [accountStore accountsWithAccountType:accountType];
if (accounts.count > 0)
{
ACAccount *twitterAccount = [accounts objectAtIndex:0];
NSArray *keys = [NSArray arrayWithObjects:@"geocode", @"count", nil];
NSArray *objects = [NSArray arrayWithObjects:@"37.781157,-122.398720,100mi", @"100", nil];
NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:objects
forKeys:keys];
SLRequest *twitterInfoRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:[NSURL URLWithString:@"https://api.twitter.com/1.1/search/tweets.json"] parameters:dictionary];
[twitterInfoRequest setAccount:twitterAccount];
// Making the request
[twitterInfoRequest performRequestWithHandler: ^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
//dispatch_async(dispatch_get_main_queue(), ^{
dispatch_async(twitterQueue, ^{
...adding object to nsmutablearray* twitterUsers
});
}];
}
}
else {
NSLog(@"No access granted");
}
}];
});
}
-(void) printUsers
{
// wait for queue to empty
dispatch_sync (twitterQueue, ^{
dispatch_async(dispatch_get_main_queue(), ^{
for (NSString* str in twitterUsers)
{
NSLog(@"%@",str);
}
});
});
}
//ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
twitter_crawler=[[TwitterCrawler alloc] initTwitterCrawler];
[twitter_crawler getTwitterUsersInPosition:position];
}
- (IBAction)pressButton:(id)sender {
[twitter_crawler printUsers];
}
twitterUsers
因此,如果用户在填充来自第一个请求的数据之前按下按钮,它将返回一个空数组。
编辑:
队列是串行的,我以这种方式创建它:
dispatch_queue_t twitterQueue = dispatch_queue_create("com.example.MyQueue", NULL);