我正在从服务器下载图片,这是我的代码。
-(void) DownloadImages
{
NSLog(@"Images count to download %lu",(unsigned long)[productID count]); // about 3000
if ([productID count] > 0)
{
// Document Directory
NSString *myDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
for (i = 0; i < [productID count]; i++)
{
@autoreleasepool // is this right of use autoreleasepool???
{
@autoreleasepool
{
[self performSelectorInBackground:@selector(UpdateUI) withObject:nil];
}
NSLog(@"image no %d", i);
NSString *imageURL = [NSString stringWithFormat:@"http://serverPath/%@/OnlineSale/images/products/%@img.jpg",clientSite,[productID objectAtIndex:i]];
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]]];
// Reference path
NSString *imagePath = [NSString stringWithFormat:@"%@/%@img.jpg",myDirectory,[productID objectAtIndex:i]];
NSData *imageData = [NSData dataWithData:UIImageJPEGRepresentation(image, 1.0f)];
[imageData writeToFile:imagePath atomically:YES];
}
}
NSLog(@"Downloading images completed...");
}
}
编辑:这是UpdateUI方法
-(void) UpdateUI
{
spinner.hidden = NO;
[spinner startAnimating];
progressCounter.hidden = NO;
status.text = @"Synchronising Product Images...";
progressCounter.text = [NSString stringWithFormat:@"%d / %lu", i,(unsigned long)[productID count]];
}
处理时,当我在模拟器时,使用的最大内存为: 超过1500张图片下载。
但是在iPad上进行测试,最大内存达到 106.9 MB ,应用程序因此消息崩溃,刚刚下载500张图片后:
并且屏幕显示以下消息:
在过去的两天里,我抓住了这一点,抓住了我的头后,没有找到任何解决方案。请帮我解决这个问题..
修改 使用autoreleasedpool的方式是对还是???
答案 0 :(得分:2)
首先,我建议在@autoreleasepool
内部包含整个for循环块。它看起来像这样:
for (i = 0; i < [productID count]; i++)
{
@autoreleasepool // is this right of use autoreleasepool???
{
[self performSelectorInBackground:@selector(UpdateUI) withObject:nil];
NSLog(@"image no %d", i);
NSString *imageURL = [NSString stringWithFormat:@"http://serverPath/%@/OnlineSale/images/products/%@img.jpg",clientSite,[productID objectAtIndex:i]];
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]]];
// Reference path
NSString *imagePath = [NSString stringWithFormat:@"%@/%@img.jpg",myDirectory,[productID objectAtIndex:i]];
NSData *imageData = [NSData dataWithData:UIImageJPEGRepresentation(image, 1.0f)];
[imageData writeToFile:imagePath atomically:YES];
}
}
如果您尝试使用@autoreleasepool
块完成的操作是处理updateUI
中分配的内存,那么这不是正确的方法。您应该将updateUI
正文括在@autoreleasepool
内。
我还建议发布updateUI
的内容;你甚至可以评论那个叫出来,看看下载是否会导致内存问题。
更一般地说,我在后台线程上更新UI似乎很可疑。作为一般做法,UI应仅在主线程上更新。 (但是没有看到updateUI
定义,我真的不能说这是否合适。)
关于使用设备或模拟器获得的不同结果,这是“正常”。当涉及内存处理时,模拟器完全不可靠,您还可以使用模拟器检测设备上没有的泄漏。
编辑:
作为一个简单的补丁,尝试这种方法:
for (i = 0; i < [productID count]; i++)
{
dispatch_async(dispatch_get_main_queue(), ^{
[self UpdateUI];
NSLog(@"image no %d", i);
NSString *imageURL = [NSString stringWithFormat:@"http://serverPath/%@/OnlineSale/images/products/%@img.jpg",clientSite,[productID objectAtIndex:i]];
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]]];
// Reference path
NSString *imagePath = [NSString stringWithFormat:@"%@/%@img.jpg",myDirectory,[productID objectAtIndex:i]];
NSData *imageData = [NSData dataWithData:UIImageJPEGRepresentation(image, 1.0f)];
[imageData writeToFile:imagePath atomically:YES];
});
}
正如您将注意到的那样,我将单独调度循环中的每个步骤。通过这种方式,邮件循环将能够更新UI。请注意,此实现不是最佳的,因为dataWithContentsOfURL
将需要一些执行(因为它需要网络访问)并且不应该在主线程上执行(但是你已经这样做了)。这应该在后台队列上发送。
答案 1 :(得分:0)
您应该使用更合适的方法来获取图像数据。 我建议你试试NSURLDownload课程。
或者,您可以使用流行的第三方网络框架之一,例如AFNetworking