gpt4 book ai didi

ios - dispatch_sync 在队列为空之前返回

转载 作者:行者123 更新时间:2023-11-28 19:09:25 26 4
gpt4 key购买 nike

我有两个类,一个 View Controller 和另一个 (TwitterCrawler) 向 Twitter API 执行网络请求。我在加载 View Controller 时发出第一个网络请求,在用户按下按钮时发出第二个网络请求。

我希望在第一个请求完成时执行第二个请求,这意味着如果用户在第一个请求完成之前按下按钮,它会等待它结束然后执行第二个。

即使我将第一个请求放在我创建的队列中,我在用户按下按钮时调用的命令 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);

最佳答案

dispatch_sync 保证它不会返回,直到通过该 API 排队的 block 被执行。不多也不少。

如果 twitterQueue 是并发队列,那么通过 dispatch_sync 入队的 block 可能会立即执行,而不管其他 block 在做什么。如果它是一个串行队列,那么该 block 将在已经入队的内容之后执行。但是,如果新项目添加到队列中,它们将在同步调度后运行。

当队列为空时做某事的想法通常不是一个有用的方法(除非你很难管理队列并且执行的最后一个项目保证是该任务的最后一个项目,可能会触发一个新的多-阻止任务并重新使用队列)。

您最好使用信号量或调度屏障或任何其他分组机制来严格控制您的并发性,包括何时对主队列进行更新。

这很好starting point document .还有一些更高级的并发指南可用。

关于ios - dispatch_sync 在队列为空之前返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17129423/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com