繁体   English   中英

没有使用NSURLConnection异步返回数据

[英]No Data Returned Using NSURLConnection Asynchronously

我似乎很喜欢一些时间
直截了当但我似乎无法工作。 我正在建设一个
从Web主机检索数据的iPhone应用程序。 我在尝试着
建立与主机的异步连接,因为我想保留
设备在连接期间释放。 (sendSynchronousRequest冻结
电话,直到请求完成。)这是我的连接代码:

//temp url to see if data is returned:
NSURL *theURL = [NSURL URLWithString:@"http://www.theappleblog.com/feed"];

NSURLRequest *dataRequest = [NSURLRequest requestWithURL:theURL
             cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
             timeoutInterval:60];

/* establish the connection */  
theConnection = [[NSURLConnection alloc]
                 initWithRequest:dataRequest
                        delegate:self
                startImmediately:YES];

if (theConnection == nil) { 
    NSLog(@"Connection Failure!");
    self.urlData = nil; 
} else {
    self.urlData = [[NSMutableData data] retain];   
}

我已经设置了所有适当的委托方法:

-(void)connection:(NSURLConnection *)connection
       didReceiveResponse:(NSURLResponse*)response
{
    [urlData setLength:0];
    UIApplication *application = [UIApplication sharedApplication];
    application.networkActivityIndicatorVisible = YES;
    NSLog(@"Received Response!");
}

-(void)connection:(NSURLConnection *)connection
       didReceiveData:(NSData*)incrementalData
{
    [self.urlData appendData:incrementalData];

    NSNumber *resourceLength = [NSNumber
              numberWithUnsignedInteger:[self.urlData length]];
    NSLog(@"resourceData length: %d", [resourceLength intValue]);
    NSLog(@"filesize: %d", self.urlDataSize);
    NSLog(@"float filesize: %f", [self.urlDataSize floatValue]);
}

-(void)connectionDidFinishLoading:(NSURLConnection*)connection
{
    NSLog(@"Connection finished loading\n");
    NSLog(@"Succeeded! Received %d bytes of data",[urlData length]);
    _isFinished = YES;
    UIApplication *application = [UIApplication sharedApplication];
    application.networkActivityIndicatorVisible = NO;
}

- (void)connection:(NSURLConnection *)connection
        didFailWithError:(NSError *)error
{
    NSLog(@"Error: %@",[error localizedDescription]);
}

正如你所看到的,我有一大堆日志消息,因为我想要
看看是否有任何事情发生。 我的连接测试
返回为TRUE但没有数据被加载。 就像我说的,我很有信心
我必须做(或不做)一些非常愚蠢的事情。 但是什么?
非常感激任何的帮助。

谢谢,劳伦斯

问题是我正在继续程序流程而不是停止允许连接完成下载。 谢谢你提出的所有建议。

一些建议:

  • 在您的第一个代码段中,而不是theConnection尝试分配给self.theConnection以确保调用属性访问器方法。 在各个地方你也可以互换self.urlDataurlData 可能想要通过self来使它们一致。

  • 您可能还希望将dataRequest为属性并通过self来确保它被保留。

  • self.urlData = [[NSMutableData data] retain]; - 你不应该需要额外的保留。 通过self为你做。 额外的保留将使它即使在完成所有操作后物体也会粘在一起并泄漏。

  • 在相关说明中,在NSLog中确保打印出每个对象的保留计数。 此外,您可能希望有一个通用的清理程序来释放这些结构(或设置self.foo = nil ),所以如果它barfs out你可以调用例程来清理东西。

  • 获取Charles或WireShark的副本(或在控制台中运行tcpdump)并观察网络流量。 它将帮助确定流程中哪个阶段失败。

最初的想法 - 是否正确保留所有这些代码的对象? 它可能正在被释放,从而解除了连接...

否则你至少应该看到回应。

那里没有什么明显的错误。 我的代码基本相同,工作正常。 我看到的唯一区别是:

  • 我使用NSURLRequestUseProtocolCachePolicy而不是NSURLRequestReloadIgnoringLocalCacheData

  • 我使用connection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self]; 而不是指定startImmediately:YES(因为它是默认值)

知道调用哪些委托方法(如果有的话)会很有帮助。 至少,您应该至少调用connectionDidFinishLoading或connectionDidFail中的一个或另一个。 如果没有,那么您的委托设置可能出现问题 - 您是否绝对确定委托方法签名是正确的,并且您正在传递正确的项目作为委托?

很难对任何事情进行归零,因为从你的问题中可以看出,如果任何NSLog语句执行的话。 请稍微清楚一下你得到的结果。

从快速浏览看,唯一看起来像潜在问题的是您在设置连接时遇到竞争条件。 如果网络速度特别快,那么在连接self.urlData之前,将会调用-connection:didReceiveData:。 我建议在启动连接或in -connection之前分配urlData:didReceiveResponse:以防止这种情况发生。

如果这不能解决问题,则需要您提供更多信息。

这不会直接回答您的问题,但您可能会考虑查看Ben Copsey的ASIHTTPRequest库,该库包含CFNetwork类并包含异步的线程请求代码,这些代码需要大量工作才能正确执行此操作。

你说这个代码使用异步方法工作正常吗? 测试该URL,它重定向到另一个,那么如果您实现重定向委托方法呢? 如果你尝试一些不同的URL怎么办?

该应用程序是否响应? runloop正在运行吗? 应用程序在启动请求后执行了什么操作 - 它是否从事件处理程序返回到runloop? (如果没有,你永远不会得到任何回调,因为它们是通过runloop传递的。)

NSURLConnection旨在用于任何类型的协议,而不仅仅是HTTP。 这意味着连接:didFail:withError被调用用于连接错误,但不用于协议错误。 你没有检查协议错误 - 你必须连接它们:didReceiveResponse:。 诀窍是传入的响应对象实际上是NSHTTPURLResponse对象。 如果你检查响应的statusCode,我敢打赌你得到一个HTTP错误,如404或服务器500。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM