dispatch_semaphore_wait不等待信号量

我开发了以下方法,它检查应用程序与服务器通信的能力。 该方法执行简单的查询,并知道如果得到结果,应该连接的应用程序(基本的ping机制)。

- (BOOL)isAppConnected { __block BOOL isConnected = NO; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [[SFRestAPI sharedInstance] performSOQLQuery:@"SELECT id FROM Account LIMIT 1" failBlock:^(NSError *e) { isConnected = NO; NSLog(@"NOT CONNECTED %@", e); NSLog(@"fail block ON THE MAIN THREAD? %hhd", [NSThread isMainThread]); dispatch_semaphore_signal(semaphore); } completeBlock:^(NSDictionary *dict) { isConnected = YES; NSLog(@"%@", dict); NSLog(@"complete block ON THE MAIN THREAD? %hhd", [NSThread isMainThread]); dispatch_semaphore_signal(semaphore); }]; // if the wait times-out we will receive a non-zero result and can assume no connection to SF //When using: DISPATCH_TIME_FOREVER the app hangs forever!! int waitResult = dispatch_semaphore_wait(semaphore, 30 * NSEC_PER_SEC); NSLog(@"waitResult: %d", waitResult); return isConnected; } 

我正在使用苹果文档中build议的“dispatch_semaphore_wait”

我的目标是等待响应或短暂超时,以确定我们是否确实有一个有效的连接。

使用上面的代码,'dispatch_semaphore_wait'永远不会实际等待,即执行不会停止在该行,但会立即继续(总是返回49作为dispatch_semaphore_wait调用的结果)。 这是除非我使用DISPATCH_TIME_FOREVER在这种情况下,应用程序永远挂起…

目前我正在从主线程调用这个方法。 我知道这是一个糟糕的主意,但我希望在重构之前能够按预期工作。

什么可能导致这种行为? 谢谢。

dispatch_semaphore_wait的参数不是延迟,而是信号量应该醒来的时间。 1月1日午夜过后30秒,你将会醒来。 1970年(或2001年,不确定)。 使用dispatch_time函数。

 - (BOOL)isAppConnected { __block BOOL isConnected = NO; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); // Add this code... dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [[SFRestAPI sharedInstance] performSOQLQuery:@"SELECT id FROM Account LIMIT 1" failBlock:^(NSError *e) { isConnected = NO; NSLog(@"NOT CONNECTED %@", e); NSLog(@"fail block ON THE MAIN THREAD? %hhd", [NSThread isMainThread]); dispatch_semaphore_signal(semaphore); } completeBlock:^(NSDictionary *dict) { isConnected = YES; NSLog(@"%@", dict); NSLog(@"complete block ON THE MAIN THREAD? %hhd", [NSThread isMainThread]); dispatch_semaphore_signal(semaphore); }]; }); int waitResult = dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); NSLog(@"waitResult: %d", waitResult); return isConnected; } 

首先,如果在主线程上调用了failcomplete块,那么你将永远等待,或者直到超时时间指定“超时”

原因是因为调用dispatch_semaphore_wait后主线程开始等待。 然后,如果您执行的SQLQLQuery调用主线程上的块,直到超时时间才会发生。

如果你指定一个永远的时间,那么信号量永远不会发出信号或放弃,这意味着你的主线程将永远等待自己。

改变等待代码 :永远不要让主线程等待

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ int waitResult = dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); NSLog(@"waitResult: %d", waitResult); }); 

而且不要像你所做的那样返回一个Bool,因为这是一个冗长的操作,你想使用一个有结果的块。

另外请确保您的performSOQLQuery()方法不在主线程上。