未调用NSURLConnection didReceiveData

我已经阅读了大量的消息,再次说同样的事情:当你使用NSURLConnection,委托方法不被调用 。 我明白,苹果的文件是不完整的,并引用不赞成的方法,这是一个耻辱,但我似乎无法find一个解决scheme。

请求的代码在那里:

// Create request NSURL *urlObj = [NSURL URLWithString:url]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:urlObj cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30]; [request setValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"]; if (![NSURLConnection canHandleRequest:request]) { NSLog(@"Can't handle request..."); return; } // Start connection dispatch_async(dispatch_get_main_queue(), ^{ self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]; // Edited }); 

…代表方法的代码在这里:

 - (void) connection:(NSURLConnection *)_connection didReceiveResponse:(NSURLResponse *)response { NSLog(@"Receiving response: %@, status %d", [(NSHTTPURLResponse*)response allHeaderFields], [(NSHTTPURLResponse*) response statusCode]); self.data = [NSMutableData data]; } - (void) connection:(NSURLConnection *)_connection didFailWithError:(NSError *)error { NSLog(@"Connection failed: %@", error); [self _finish]; } - (void) connection:(NSURLConnection *)_connection didReceiveData:(NSData *)_data { [data appendData:_data]; } - (void)connectionDidFinishDownloading:(NSURLConnection *)_connection destinationURL:(NSURL *) destinationURL { NSLog(@"Connection done!"); [self _finish]; } 

这里没有太多的错误检查,但是我确定了几件事情:

  • 无论发生什么, didReceiveData不会被调用,所以我没有得到任何数据
  • …但数据传输(我使用tcpdump检查)
  • …和其他方法被称为成功。
  • 如果我使用NSURLConnectionDownloadDelegate而不是NSURLConnectionDataDelegate ,一切正常,但我不能保留下载的文件(这是一个已知的错误)
  • 该请求在不完整的内存pipe理之前不会被释放
  • 如果我在互联网上的某个地方使用标准的HTML页面作为我的URL,没有什么变化
  • 请求从主队列中启动

我不想使用第三方库,因为最终,这些请求将被包含在我自己的库中,我想尽量减less依赖关系。 如果必须的话,我会直接使用CFNetwork ,但是在你知道什么的时候会是一个巨大的痛苦。

如果你有任何想法,这将有很大的帮助。 谢谢!

我喜欢使用sendAsynchronousRequest方法..在连接期间信息较less,但代码更清晰。

  [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){ if (data){ //do something with data } else if (error) NSLog(@"%@",error); }]; 

从苹果:

默认情况下,当前线程在默认模式下创build连接。 如果使用initWithRequest:delegate:startImmediately:方法创build连接,并为startImmediately参数提供NO,则可以在使用start方法启动它之前,在不同的运行循环或模式中调度连接。 您可以在多个运行循环和模式中安排连接,也可以在多个模式的同一个运行循环中进行连接。

除非有理由在[NSRunLoop currentRunLoop]中明确运行它,否则可以删除这两行:

 [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; [connection start]; 

或将模式更改为NSDefaultRunLoopMode

我遇到了同样的问题。 非常烦人,但似乎如果你实现这个方法:

 - (void)connectionDidFinishDownloading:(NSURLConnection *)connection destinationURL:(NSURL *)destinationURL 

然后connection:didReceiveData:永远不会被调用。 你必须使用connectionDidFinishLoading:相反…是的,文档说它已被弃用,但我认为这只是因为此方法从NSURLConnectionDelegate NSURLConnectionDataDelegate移动。

NSURLConnection API表示“..delegate方法启动相关NSURLConnection对象的asynchronous加载操作的线程上调用”。

由于dispatch_async会启动新线程,并且NSURLConnection不会传递给其他威胁callback,因此不要使用带有NSURLConnection的dispatch_async

您不必担心冻结的用户界面,NSURLConnection只提供asynchronous加载的控件。

如果你有更多的文件需要下载 ,你可以在第一回合启动一些连接,然后完成,在connectionDidFinishLoading:方法中你可以开始新的连接。

 int i=0; for (RetrieveOneDocument *doc in self.documents) { if (i<5) { [[NSURLConnection alloc] initWithRequest:request delegate:self]; i++; } } .. -(void)connectionDidFinishLoading:(NSURLConnection *)connection { ii++; if(ii == 5) { [[NSURLConnection alloc] initWithRequest:request delegate:self]; ii=0; } } 

一个可能的原因是传出的NSURLRequest被设置为具有HEAD-HTTPMethod方法。 尽pipe如此,很难做到这一点!