0

我创建了一个类,用于在我的 iOS 应用程序中获取服务器端数据,基于 NSURLConnection,将获取的数据转发给委托进行处理。

下载 text/json 时,这非常有效。

我现在正在扩展以获取一些 png 图像,但无法获取数据。

我发现它在 didReceiveData 调用中中断,其中 [receivedData appendData:data] 对接收到的图像数据没有做任何事情。

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    // Append the new data to receivedData.
    [receivedData appendData:data];
}

我将数据放入此方法(NSData >0 字节),但调用 [receivedData appendData:data] 不会更改 receivedData 的大小(仍为 0 字节)。

由于这适用于文本而不是图像数据,我相信它与字符集或编码有关,但在这方面找不到任何东西。

任何帮助表示赞赏。


使用请求的代码示例更新:

在进行调用的方法中:

NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
    // Create the NSMutableData to hold the received data.
    receivedData = [NSMutableData data];
    // Also tried with no change in behaviour
    // receivedData = [[NSMutableData alloc] initWithLength:0];
} else {
    // Inform the user that the connection failed.
}

我的didReceiveResponse

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    [receivedData setLength:0];
}

另一个更新

结果发现问题归结为并发性,因为我同时触发了该类的三个实例以异步获取三个文件。问题是第一个版本receivedData在完成破坏其他两个实例的响应时发布。

我如何确保类的每个实例都有自己的receivedData可玩性?


最后的注意事项 使用 MutableArrays 的字典来检索数据可以解决并发问题。

似乎将 MutableArray 定义为类的私有属性也会为每个实例创建一个数组。

@interface MyClass(){
    @private NSMutableData * receivedData;
}
4

2 回答 2

1

你有没有初始化receivedData

这样的事情会做到这一点:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    if(!receivedData)
    {
        receivedData = [NSMutableData data];
    }
    [receivedData appendData:data];
}

一种更快的方法是在您启动实际请求之前对其进行初始化(这样就不会在每次接收到数据时都对其进行检查)。

还记得receivedData在您的请求完成并且您完成提取它时为零,以便为下一个请求做好准备。


这是并发请求的一种解决方案:

代替单个 NSMutableData 属性,创建一个 NSMutableDictionary 以便您可以一次挂起多个实例。

NSMutableDictionary *receivedData

现在,一旦你把你的 NSURLConnection (我们称之为它urlConnection)放在一起,你就可以创建一个新的唯一数据对象并将它放入你的字典中。您应该能够使用连接的字符串描述作为您的唯一键。

if(!receivedData)
  receivedData = [NSMutableDictionary dictionary];

NSMutableData *dataObject = [NSMutableData data];
[receivedData setObject:dataObject forKey:[urlConnection description]];

现在你可以这样做:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
  NSMutableData *currentData = (NSMutableData*)[receivedData objectForKey:[connection description]];
  [currentData.appendData:data];
}

removeObjectForKey连接完成后,请记住在不再需要数据对象时调用以删除它们。

于 2012-06-29T14:51:15.503 回答
0

我找到了一种可行的解决方法,即将在 JSON 响应中编码的 base64 数据库发送到设备,并在设备上本地使用文件之前对其进行解码。

这也证明非常有用,因为它可以在一个请求中传输所需的三个文件。

于 2012-07-02T18:33:49.743 回答