未调用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如此,很难做到这一点!