10

这个 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
4

5 回答 5

7

在后台队列中运行请求,这样它就不会阻塞发生 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];

    });
于 2013-10-30T12:13:58.130 回答
3

Add delegate <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
}

This method more better to download data.. It wont use main thread so the app wont hang.. I hope it will be more useful for you

于 2013-10-30T12:08:40.537 回答
2

cachedResponseForRequest此代码在其他上下文中有效,因此很明显它正在发生,因为调用是从NSURLCache. 在其他地方运行它工作正常。

因为这是为了在嵌入式UIWebView和服务器中的 AJAX 调用之间启用代理(为了不必在 JS 中重写 API 请求签名代码),所以我使用Marcus Westin 的 WebViewProxy 类解决了这个问题。

于 2013-11-15T18:07:17.700 回答
-1

当您的请求通过响应成功时,您的 NSLog 将执行,因为 sendSynchronousRequest 方法在主线程上工作。

于 2013-10-30T12:03:56.820 回答
-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.
}
于 2013-10-30T12:01:49.663 回答