gpt4 book ai didi

ios - iOS 中的内存管理,模拟器与 idevice 给出不同的结果

转载 作者:行者123 更新时间:2023-11-28 22:05:40 27 4
gpt4 key购买 nike

我正在从服务器下载图片,这是我的代码。

-(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 张图片下载。

enter image description here

但在 iPad 上测试时,最大内存达到 106.9 MB 并且在下载 500 张图片后应用程序崩溃并显示此消息:

enter image description here

屏幕显示此消息: enter image description here

这两天我一直卡在这个问题上,摸不着头脑也没有找到任何解决办法。请帮我解决这个问题..

编辑:使用 autoreleasedpool 方式是否正确???

最佳答案

首先,我建议将整个 for 循环 block 包含在 @autoreleasepool 中。它看起来像这样:

   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 block 完成的是处理在 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 将花费一些时间来执行(因为它需要网络访问)并且不应在主线程上执行(但您已经这样做了) .那应该在后台队列上分派(dispatch)。

关于ios - iOS 中的内存管理,模拟器与 idevice 给出不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24080482/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com