NSURLConnection sendSynchronousRequest - 后台到前台

6
我正在使用sendSynchronousRequest从服务器获取数据。我知道同步会等待直到收到该请求的数据。
但是问题出在当用户错误地输入一些不存在的URL,然后尝试获取响应时。在这种情况下,如果用户进入后台,然后再回到前台,它只显示黑屏。它只显示状态栏。也没有显示任何后台应用程序。我必须按Home按钮才能退出我的应用程序。
在模拟器上,在1分钟后,它会向我显示“请求超时”的消息(不会崩溃)。
在设备上,应用程序在1分钟内崩溃。
有什么建议吗?任何帮助。这确实是我应用程序中的一个严重问题。
谢谢。

在崩溃之前,控制台上是否有任何输出? - iamsult
9个回答

14

就像Julien所说的一样,看门狗正在关闭你的应用程序。回答一些问题:

  • 为什么这只在模拟器上发生? 因为当你调试时,看门狗会让你的应用程序保持稳定,它可以花费时间。
  • 为什么这只在用户输入错误的url时发生? 由于系统超时,如果找不到服务器,系统将尝试60秒钟。
  • 所以问题是同步还是异步? 不是,问题是线程,你可以在后台线程中执行相同的操作,只是不要在主线程上执行它,看门狗就会离开你。
  • 为什么应用程序启动时屏幕是黑色的? 记住,你正在主线程上制作阻塞的东西,即绘制线程...

希望这就是全部。如果我漏掉了什么,请告诉我。


9
为什么不为您的连接设置超时?
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];

这应该在若干秒后释放同步等待,这样就可以解决您的问题,而不必采用异步调用(有时并不是正确的解决方案)。
我知道这个方法可以正常工作,因为这是我检查是否连接到某个 VPN 的方式(其中可达性标志完全失效)。

3

我不确定,但他没有提到下载。在主线程上进行同步连接可能对于登录来说是有意义的。 - superandrew
1
我认为在主线程上使用同步连接进行登录操作是没有意义的。最好异步启动它,显示活动指示器并禁用用户交互。我建议您创建一个包含带有完成处理程序块的方法的登录类。(如果您想要一个示例,可以查看iOs 5中可用的TWRequest类) - Julien

2

关联

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);
}

0

试试这个:

#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大小。

0

我认为你首先需要测试用户数据是否正确,只有在数据正确的情况下才发送请求,否则提示用户“请输入正确的数据”...

或者

当响应数据解析失败时,你也可以创建协议委托方法,即FinishWithError,以便你能够完成最后的用户界面。


0

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


0

使用ASIHttpRequest类代替NSURLConnection,它只是NSURURLConnection的包装器,并具有非常简单的回调函数,您还可以设置请求完成的时间。请通过此链接了解更多信息http://allseeing-i.com/ASIHTTPRequest/


NSURLConnection在我的情况下正常工作,只有在上述情况下才会崩溃。 - JiteshW
ASIHttpRequest完全不使用NSURLConnection。而且ASIHttpRequest已不再处于活跃开发阶段。 - hooleyhoop

-1

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

我认为这会解决你的问题。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接