NSURLConnection sendSynchronousRequest似乎挂起

时间:2013-10-30 11:59:05

标签: ios objective-c

这个HTTP调用似乎悬而未决,我看不出原因。调用后的日志行永远不会运行。

我几乎肯定会做一些非常愚蠢的事情,但如果有人能发现它是什么我会感激不尽。据我所知,我的代码等同于文档。

我使用的URL似乎并不重要,服务器永远不会记录HTTP请求(如果指向一个)。

NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com/"]];

NSURLResponse *res = nil;
NSError *err = nil;

NSLog(@"About to send req %@",req.URL);

NSData *data = [NSURLConnection sendSynchronousRequest:req returningResponse:&res error:&err];

NSLog(@"this never runs");

有什么想法吗?

更新

感谢到目前为止发布的所有人。还在看问题。更详细一点:

  • 正在设备上测试代码
  • 其他HTTP调用工作正常,如果这是一个网络问题,这是一个非常重要的
  • 代码已经超过正常超时。我知道它挂了20多分钟。我当时杀了它,但我认为它会继续挂起。
  • 我目前没有使用代表但不打算参加,见下文。
  • 在应用程序的其他地方我使用sendAynchronousRequest但在这个实例中我需要传递一个返回值(我不在主线程上),所以sendSynchronousRequest是我唯一的选择知道。
  • 如果重要,上下文是我正在实施NSURLCache协议,特别是cachedResponseForRequest方法,这需要我返回NSCachedURLResponse

5 个答案:

答案 0 :(得分:8)

在后台队列中运行请求,以便它不会阻止发生UI更新的主线程:

 dispatch_queue_t myQueue = dispatch_queue_create("myQueue", NULL);

    // execute a task on that queue asynchronously
    dispatch_async(myQueue, ^{
NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com/"]];

NSURLResponse *res = nil;
NSError *err = nil;

NSLog(@"About to send req %@",req.URL);

NSData *data = [NSURLConnection sendSynchronousRequest:req returningResponse:&res error:&err];

    });

答案 1 :(得分:3)

添加委托<NSURLConnectionDataDelegate>

NSURL *url = [[NSURL alloc]initWithString:[NSString stringWithFormat:@"Your string here"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
    [connection start];//It will start delegates


-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    [received_data setLength:0];//Set your data to 0 to clear your buffer 
}

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{

    [received_data appendData:data];//Append the download data..
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    //Use your downloaded data here
}

这种方法更好地下载数据..它不会使用主线程,所以应用程序不会挂起..我希望它对你更有用

答案 2 :(得分:2)

此代码适用于其他上下文,因此很明显它正在发生,因为调用是从cachedResponseForRequest的{​​{1}}方法进行的。在其他地方运行它可以正常工作。

由于这是为了在嵌入式NSURLCache中的AJAX调用和服务器之间启用代理(为了不必在JS中重写API请求签名代码),我使用{{{ 3}}这是一种享受。

答案 3 :(得分:-1)

当您的请求成功响应时,NSLog将执行,因为sendSynchronousRequest方法适用于主线程。

答案 4 :(得分:-2)

它是synchronous方法 - 即它在主线程上运行。因此,您的应用程序将挂起 - 它将等待数据下载。

要防止它:使用sendAsynchronousRequest方法。它会在后台线程上运行此过程并且不会破坏您的应用程序,或者只是 - 不会让它挂起

以下是sendAsynchronousRequest

的使用方法
NSURL *url = [NSURL URLWithString:@"YOUR_URL_HERE"];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
    //the NSData in the completion handler is where your data is downloaded.
}];

考虑到所有情况,我认为由于您的委托声明而存在问题。因此,声明<NSURLConnectionDataDelegate>并声明NSMutableDatamyData对象和NSURLConnectionurlConnection作为属性。现在使用:

NSURL *url = [NSURL URLwithString : @"YOUR_URL_HERE"];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
*urlConnection = [NSURLConnection connectionWithRequest:urlRequest delegate:self];


-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    [myData setLength:0]; 
}

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{

    [myData appendData:data];
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    //You can use the complete downloaded data - NSMutableData here.
}