NSURLConnection sendSynchronousRequest – 背景到前景

我使用sendSynchronousRequest从服务器获取数据。 我知道同步将等待,直到收到该请求的数据。

但是,当用户错误地进入一些不存在的url,并试图得到回应时,问题就来了。 在这种情况下,如果用户进入背景而不是进入前景,则只显示黑屏。 它只显示状态栏。 也没有显示任何后台应用程序。 我必须按下主页button来出我的应用程序。

在模拟器上,超过1分钟后,显示“请求超时”(没有崩溃)消息。

在设备上,1分钟内应用程序崩溃。

任何build议。 任何帮助。 这在我的应用程序中确实是一个严重的问题。

谢谢。

就像朱利安说的,看门狗正在杀死你的应用程序。 回答一些问题:

  • 为什么这只发生在模拟器上? 因为当你正在debugging看门狗的时候,你的应用程序就不能运行,这可能需要一些时间
  • 为什么只有当用户input错误的url时才会发生这种情况? 由于系统超时,如果找不到服务器,系统会继续尝试60秒。
  • 所以问题是同步与asynchronous? 不,问题是线程,你可以在后台线程中执行相同的操作,只要不在主线程中执行,看门狗就会离开你。
  • 为什么应用程序出现时屏幕是黑色的? 记住,你正在阻塞主线程上的东西,线程绘制…

希望这一切。 让我知道如果我错过了什么。

为什么不为连接设置超时?

NSString *urlString = TEST_CONNECTION; NSError *error = nil; NSHTTPURLResponse *response = nil; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:5.0]; NSData *conn = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; 

这应该释放几秒钟后的同步等待,这应该解决您的问题,而不用asynchronous调用(这有时不是正确的解决scheme)

我知道这工作正常,因为这是我如何检查,如果我连接到某个VPN(可达标志完全失败)。

你应该看看这篇文章: https : //developer.apple.com/library/ios/#qa/qa1693/_index.html

IO包含一个看门狗 ,如果你的应用程序在主线程上的操作被阻塞了很多时间,这个将被杀死。 (关于看门狗的更多细节: http : //en.wikipedia.org/wiki/Watchdog_timer )

所以如果你想下载的东西,不要在主线下载。

涉及

 UIImage *image = [self.imgCache objectForKey:urlString]; if(!image){ NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString] cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:60.0]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSURLResponse *response = nil; NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil]; NSLog(@"%@",response); UIImage *img = [UIImage imageWithData:data]; // if(img) { dispatch_sync(dispatch_get_main_queue(), ^{ [self.imgCache setObject:img forKey:urlString]; completionBlock(img); }); } }); } else{ completionBlock(image); } 

使用ASIHttpRequest类而不是NSURLConnection,它只是包装NSURLConnection而已,而且有非常简单的callback,你也可以设置时间来完成一个请求。 请通过此链接了解更多信息http://allseeing-i.com/ASIHTTPRequest/

我认为你首先必须testing用户数据是否正确,只有正确的,发送请求,否则提示用户“请input正确的数据”… … –

要么

当你的数据parsing失败。 你也可以使协议委托方法,即FinishWithError,所以你想出了你的最后一个用户界面。

试试这个:

 #import "ASIHTTPRequest.h" //In a method [self performSelectorInBackground:@selector(DownLoadImageInBackground:) withObject:imgUrlArr]; -(void) DownLoadImageInBackground:(NSArray *)imgUrlArr1 { NSURL * url = [Image URL]; ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; [request setDelegate:self]; [request startAsynchronous]; } -(void)requestFailed:(ASIHTTPRequest *)request { NSLog(@"URL Fail : %@",request.url); NSError *error = [request error]; // you can give here alert too.. } -(void)requestFinished:(ASIHTTPRequest *)request { NSData *responseData = [request responseData]; UIImage *imgInBackground = [[UIImage alloc] initWithData:responseData]; [imageView setImage: imgInBackground]; } 

这可能会帮助你:我也一次加载一些图像,所以没有适当数据的图像显示黑屏。 为了避免这种情况,请尝试调整您的imageview的大小。

在开始请求之前,您可以检查URL的可达性。 苹果有Reachability方法这样做。 但它更容易使用包装。 例如ASIReachability

我认为应用程序崩溃是因为当用户input错误的URL ,你没有得到任何数据,并且你正在使用这个“返回的” nil NSData做东西。

我认为这将解决您的问题

 NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; if(data!=nil){ /// } else { NSLog(@"NO DATA"); }