7

我正在使用 NSURLConnection 通过 HTTP 获取图像,如下所示 -

NSMutableData *receivedData;

- (void)getImage {
    self.receivedData = [[NSMutableData alloc] init];
    NSURLConnection *theConnection = // create connection
}

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

-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
   [connection release];

   UIImage *theImage = [UIImage imageWithData:receivedData];
}

通常它工作得很好,但有时我看到这个被记录了 - :损坏的JPEG数据:数据段的过早结束

此时,图像还没有完全渲染。我会看到大概 75%,然后右下角是一个灰色框。

关于如何解决这个问题的任何想法?我是否不正确地构建了我的图像?

4

5 回答 5

9

您的 HTTP 代码看起来正确。加载完成后,您可能希望记录 receivedData 的大小,并将其与服务器上图像的预期大小进行比较。如果它是预期的大小,那么可能图像本身在服务器上已损坏。

于 2009-06-30T18:18:33.800 回答
3

ASI-HTTP 可以解决这个问题。

NSURL *coverRequestUrl = [NSURL URLWithString:imageStringURL];
ASIHTTPRequest *coverRequest = [[ASIHTTPRequest alloc] initWithURL:coverRequestUrl];
[coverRequest setDelegate:self];
[coverRequest setDidFinishSelector:@selector(imageRecieved:)];

[appDelegate.queue addOperation:coverRequest];
[appDelegate.queue go];

我在 appDelegate 中的队列变量是 ASINetwork 队列对象。因为我发送异步请求,所以我使用它。

- (void)imageRecieved:(ASIHTTPRequest *)response
{
    UIImage *myImage = [UIImage imageWithData:[response responseData]];
}
于 2009-11-17T05:08:32.547 回答
2

我通过使用 NSMutableDictionary 解决了这个问题。

NSMutableDictionary *dataDictionary;

在我的 loadData 函数中,我定义了我的数据:

NSMutableData *receivedData = receivedData = [[NSMutableData alloc] init];

然后我将数据加载到我的字典中,其中键是 [theConnection description],对象是我的数据。

[dataDictionary setObject:receivedData forKey:[theConnection description]];

这样,在委托中,我可以查找传递给委托的连接的正确数据对象并保存到正确的数据实例,否则我最终会遇到 JPEG 修改/损坏问题。

在 didReceiveData 中,我输入:

//get the object for the connection that has been passed to connectionDidRecieveData and that object will be the data variable for that instance of the connection.
NSMutableData *theReceivedData = [dataDictionary objectForKey:[connection description]];

//then act on that data
[theReceivedData appendData:data];

同样,在 didReceiveResponse 中,我输入:

NSMutableData *theReceivedData = [dataDictionary objectForKey:[connection description]];
[theReceivedData setLength:0];

并在 connectionDidFinishLoading: NSMutableData *theReceivedData = [dataDictionary objectForKey:[connection description]]; img = [[UIImage alloc] initWithData:theReceivedData];

这似乎工作得很好。顺便说一句,我的代码基于Apple 的 NSUrlConnection 教程,并添加了 NSMutableDictionary 来跟踪各个连接。我希望这有帮助。如果您希望我发布我的完整图像处理代码,请告诉我。

于 2010-12-05T18:06:54.873 回答
1

我也看到了这个。如果您将数据保存到文件中,然后将数据读回图像中,则可以完美运行。我怀疑 jpeg 图像数据中有 http 标头信息。

希望有人找到解决方案,因为保存到文件的解决方法很糟糕。

// problem

UIImage *newImage = [UIImage imageWithData:receivedData];

// crappy workaround

[receivedData writeToFile:[NSString stringWithFormat:@"a.jpg"] atomically:NO];
UIImage *newImage = [UIImage imageWithContentsOfFile:@"a.jpg"];
于 2009-09-04T22:21:18.633 回答
0

使用复制 NSData 内容receivedData = [NSData dataWithBytes:receivedData.bytes length:receivedData.length]也可能会有所帮助(而且它比保存到磁盘和从磁盘读取更有效)。

一个可能的原因是原始 receivedData 对象不保留其内容(例如,当使用创建时[NSData dataWithBytesNoCopy:length:])并且您在它们被释放后尝试读取它们。

NSData当您在创建对象的线程的另一个线程上遇到此问题时,很可能出现这种情况。

于 2014-05-06T19:37:30.067 回答