NSURLConnectionasynchronous不起作用

我试图做一个asynchronousNSURL请求,但我得到所有“假”。

-(BOOL)checkConnectionForHost:(NSString*)host{ BOOL __block isOnline = NO; NSURLRequest *request = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:host] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:1]; [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { if([(NSHTTPURLResponse*)response statusCode]==200){ isOnline = TRUE; } }]; NSLog(@"%i",isOnline); return isOnline; } 

此外,这个代码被称为“6”次,当我实际上只是用它:

 -(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 

并且在我的数据源中只有3个单元格或3个项目。 第一次在Objective-C中处理asynchronous和callback,所以一个详细的答案将不胜感激! 谢谢!

你应该认识到这个问题本质上是asynchronous的。 你不能同步方法解决它。 也就是说,您接受的解决scheme只是一个精心制作的,不太理想的包装,最终会导致asynchronous。

更好的方法是使用完成处理程序的asynchronous方法,例如:

 typedef void (^completion_t)(BOOL isReachable); -(void)checkConnectionForHost:(NSString*)host completion:(completion_t)completionHandler; 

您可以实现如下(即使请求不是检查可达性的最佳select):

 -(void)checkConnectionForHost:(NSString*)host completion:(completion_t)completionHandler { NSURLRequest* request = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:host]]; [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { if (completionHandler) { completionHandler(connectionError == nil && [(NSHTTPURLResponse*)response statusCode]==200); } }]; } 

请注意:

  • 不要将超时设置为与原始代码一样短。
  • 完成处理程序将在一个专用线程上被调用。

用法:

 [self checkConnectionForHost:self.host completion:^(BOOL isReachable){ dispatch_async(dispatch_get_main_queue(), ^{ self.reachableLabel.text = isReachable ? @"" : @"Service unavailable"; }); }]; 

asynchronous调用将并行执行,其结果将在完成块中接收。 在你的情况下,return语句将在asynchronous请求完成之前执行。 这将永远是假的。

您应该为此使用同步请求,并处理不阻止用户界面。

 -(BOOL)checkConnectionForHost:(NSString*)host{ BOOL isOnline = NO; NSURLRequest *request = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:host] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:1]; NSHTTPURLResponse *response; NSError *error; NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; NSLog(@"Response status Code : %d",response.statusCode); isOnline = response.statusCode == 200; return isOnline; } 

您可以在派遣队列中使用该方法,

 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul); dispatch_async(queue, ^{ BOOL status = [self checkConnectionForHost:@"http://google.com"]; NSLog(@"Host status : %@",status ? @"Online" : @"Offline"); }); 

你的isOnline可能被设置为YES,但它是asynchronous发生的。 在注销isOnline的值后,它几乎肯定会执行。 所以你应该把你的NSLog()调用到你传递给asynchronousURL请求的处理程序的块中。