没有使用NSURLConnection异步返回数据

时间:2009-04-26 16:50:43

标签: iphone objective-c cocoa-touch asynchronous nsurlconnection

我正忙着做一些看似相似的事情 直截了当但我似乎无法工作。我正在建设一个 从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但没有数据被加载。就像我说的那样,我确定 我必须做(或不做)真正愚蠢的事情。但是什么呢? 任何帮助都将非常感激。

谢谢,劳伦斯

9 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

一些建议:

  • 在您的第一个代码段中,而不是theConnection尝试分配给self.theConnection以确保调用属性访问器方法。在不同的地方,您还可以互换self.urlDataurlData。可能希望通过self

  • 使它们保持一致
  • 您可能还希望dataRequest属性为self并通过self.urlData = [[NSMutableData data] retain];以确保其被保留。

  • self - 您不应该需要额外的保留。通过self.foo = nil为您完成。额外的保留将使它即使在完成所有操作后也会粘在一起并泄漏。

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

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

  • 我使用NSURLRequestUseProtocolCachePolicy而不是 NSURLRequestReloadIgnoringLocalCacheData

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

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

答案 4 :(得分:0)

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

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

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

答案 5 :(得分:0)

这不能直接回答你的问题,但你可能会考虑查看Ben Copsey的ASIHTTPRequest库,它包含CFNetwork个类,并包含需要大量工作的异步,线程化请求代码做得恰到好处。

答案 6 :(得分:0)

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

答案 7 :(得分:0)

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

答案 8 :(得分:0)

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