【问题标题】:NSUrlConnectionDelegate not calling methods to load dataNSUrlConnectionDelegate 不调用方法来加载数据
【发布时间】:2012-04-18 00:58:17
【问题描述】:

我已经看过NSURLConnectionDelegate connection:didReceiveData not working,但似乎没有任何好的结果,所以我很好奇为什么我无法获得任何数据。

我在didReceiveResponsedidReceiveData 中设置了断点。

它确实打印出“连接成功”,所以我知道连接已启动。

我正在使用 ARC 进行内存管理。

- (void)load {
        request = [NSMutableURLRequest requestWithURL:myURL
                                                           cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
                                                       timeoutInterval:60];

    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    if (conn) {
        [conn start];
        NSLog(@"connection succeeded, %s", [myURL description]);  
        responseData = [NSMutableData data];
    } else {
        NSLog(@"connection failed");
    }
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    responseData = [[NSMutableData alloc] init];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [responseData appendData:data];
}

更新:

要了解我是如何测试这个的,请查看Asynchronous unit test not being called by SenTestCase

我确实实现了 jonkroll 提到的两种方法,在他的回答中,我只是没有显示它们,但是它们也没有被调用。

我添加 [conn start] 只是因为它不起作用,我希望这可以解决它,但没有这样的运气。

【问题讨论】:

    标签: ios5 asynchronous


    【解决方案1】:

    当你像这样声明你的连接时:

    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    

    您正在创建一个本地指针。当你的方法完成时,因为它是对NSURLConnection 的最后一个强引用,ARC 会释放它。您需要使用强 ivar(和/或)属性来保持对您创建的 NSURLConnection 的强引用。

    编辑

    这是我在示例项目中测试的基本代码示例。试一试。详细日志记录会有所帮助。

    @implementation <#Your class here#> {
        // With ARC ivars are strong by default 
        NSMutableData *_downloadedData;
        NSURLConnection *_connection;
    }
    -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
        NSHTTPURLResponse *realResponse = (NSHTTPURLResponse *)response;
        if (realResponse.statusCode == 200){ 
            // Really any 2** but for example
            _downloadedData = [[NSMutableData alloc] init];
            NSLog(@"Good response");
        } else {
            NSLog(@"Bad response = %i",realResponse.statusCode);
        }
    }
    -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
        if (connection == _connection){
            [_downloadedData appendData:data];
            NSLog(@"Getting data...");
        }
    }
    -(void)connectionDidFinishLoading:(NSURLConnection *)connection{
        if (connection == _connection){
            _connection = nil;
            NSLog(@"We're done, inform the UI or the delegates");
        }
    }
    -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
        _connection = nil;
        NSLog(@"Oh no! Error:%@",error.localizedDescription);
    }
    - (void)load {
        NSURL *url = [NSURL URLWithString:@"http://www.google.com/"];
        NSURLRequest *request = [NSMutableURLRequest requestWithURL:url
                                          cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
                                      timeoutInterval:60];
        // Assign strong pointer to new connection
        _connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
        NSLog(@"Connection was initialized? = %@",(!!_connection)?@"YES":@"NO");
    }
    @end
    

    【讨论】:

    • 我将 conn 更改为:@property NSURLConnection *conn;但我得到相同的结果,没有收到数据。在等待超过 90 秒后,我的单元测试停止等待并失败。
    • 我还不确定有什么区别,但它现在可以工作了,谢谢你。
    【解决方案2】:

    NSURLConnection 方法initWithRequest 启动一个从 url 获取数据的异步请求。因为请求是异步完成的,所以您不能期望以调用请求的相同方法处理响应。相反,您需要在 NSURLConnection 的委托回调方法中这样做。您已经实现了didReceiveResponse:didReceiveData:,但还有其他一些对您有用的。

    如果您想查看回复的内容,您应该在 connectionDidFinishLoading: 中查看

    - (void)connectionDidFinishLoading:(NSURLConnection *)connection
    {
        // response is complete, do something with the data
        NSLog(@"%@", responseData);
    }
    

    您的代码打印出“连接成功”这一事实并不意味着请求成功,只是表示成功创建了 NSURLConnection 对象。要测试连接是否有问题,可以实现委托方法connection:didFailWithError:

    - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
    {
        NSLog(@"Connection failed! Error - %@ %@",
              [error localizedDescription],
              [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
    }
    

    也无需致电[conn start]。调用initWithRequest:时会自动启动请求

    我建议阅读 Apple 在 Using NSURLConnection 上的文档以了解更多详细信息。

    【讨论】:

    • 谢谢。我添加了 [conn start] 因为它不起作用,并且我还实现了其他方法,但是根据我的日志记录,它们似乎都没有做任何事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-27
    • 2012-07-19
    • 2021-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-25
    相关资源
    最近更新 更多