gpt4 book ai didi

iphone - UIImagePicker 的内存问题

转载 作者:行者123 更新时间:2023-12-03 20:48:53 27 4
gpt4 key购买 nike

我正在构建一个应用程序,它有几个不同的部分,所有这些部分都非常注重图像。它与我客户的网站相关,他们是“高设计”类型的服装。

该应用程序的一部分是从相机或库上传的图像,以及显示缩略图网格的表格 View 。相当可靠的是,当我处理 UIImagePickerControl 的相机版本时,我会因为内存不足而受到打击。如果我在应用程序的该部分徘徊一段时间,我偶尔会在调试器中出现“status:10 (SIGBUS)”崩溃,并且不会重复。

在内存不足警告时,应用程序该方面的 Root View Controller 会转到我的数据管理单例,遍历缓存数据数组,并删除最大的部分,即与每个条目关联的图像。因此:

- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Low Memory Warning"
message:@"Cleaning out events data"
delegate:nil
cancelButtonTitle:@"All right then."
otherButtonTitles:nil];
[alert show];
[alert release];

NSInteger spaceSaved;

DataManager *data = [DataManager sharedDataManager];
for (Event *event in data.eventList) {
spaceSaved += [(NSData *)UIImagePNGRepresentation(event.image) length];
event.image = nil;
spaceSaved -= [(NSData *)UIImagePNGRepresentation(event.image) length];
}

NSString *titleString = [NSString stringWithFormat:@"Saved %d on event images", spaceSaved];

for (WondrMark *mark in data.wondrMarks) {
spaceSaved += [(NSData *)UIImagePNGRepresentation(mark.image) length];
mark.image = nil;
spaceSaved -= [(NSData *)UIImagePNGRepresentation(mark.image) length];
}

NSString *messageString = [NSString stringWithFormat:@"And total %d on event and mark images", spaceSaved];

NSLog(@"%@ - %@", titleString, messageString);

// Relinquish ownership any cached data, images, etc that aren't in use.
}

如您所见,我正在(糟糕的)尝试查看我正在释放的内存空间。我知道它并没有告诉我 UIImage 本身的实际内存占用量,但它至少给了我一些数字,所以我可以看到正在发生一些事情。 (对于我构建 NSLog 消息的笨拙方式感到抱歉——我本来打算触发另一个 UIAlertView,但意识到记录它会更有用。)

非常可靠的是,在应用程序的图像部分闲逛一段时间后,我将拉出相机界面并快速连续获得低内存 UIAlertView 三到四次。这是我上次看到它时的 NSLog 输出:

2010-05-27 08:55:02.659 EverWondr[7974:207] Saved 109591 on event images - And total 1419756 on event and mark images
wait_fences: failed to receive reply: 10004003
2010-05-27 08:55:08.759 EverWondr[7974:207] Saved 4 on event images - And total 392695 on event and mark images
2010-05-27 08:55:14.865 EverWondr[7974:207] Saved 4 on event images - And total 873419 on event and mark images
2010-05-27 08:55:14.969 EverWondr[7974:207] Saved 4 on event images - And total 4 on event and mark images
2010-05-27 08:55:15.064 EverWondr[7974:207] Saved 4 on event images - And total 4 on event and mark images

然后不久之后我们就得到了 SIGBUS 导出。情况就是这样。现在我的具体问题:

我看到这种情况发生的时间是当 UIPickerView 的相机光圈关闭时。我单击按钮拍照,它会执行“单击”动画,并且 Instruments 显示我的内存占用量从大约 10mb 到大约 25mb,并坐在那里直到图像传递到我的 UIViewController,其中使用量下降到 10 或又是11mb。如果我们在没有内存警告的情况下完成了这一切,我们就很成功,但很可能我们没有。我能做些什么来让它不那么贵吗?

其次,我启用了 NSZombies。我是否正确理解这实际上阻止了内存被释放?我是否让我的应用程序处于不公平的测试环境中?

第三,有什么方法可以以编程方式获取我的内存使用情况吗?或者至少是 UIImage 对象的用法?我已经浏览了文档,但没有看到任何相关内容。

最佳答案

这些函数让您了解总内存使用量和总可用内存。我的应用程序中碰巧有一个 1 秒计时器,它每秒记录已用和可用内存空间(如果其中任何一个更改 > 0.5mb),它可以帮助我更好地了解正在发生的情况:

#import "mach/mach.h"

vm_size_t usedMemory(void) {
struct task_basic_info info;
mach_msg_type_number_t size = sizeof(info);
kern_return_t kerr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size);
return (kerr == KERN_SUCCESS) ? info.resident_size : 0; // size in bytes
}

natural_t freeMemory(void) {
mach_port_t host_port = mach_host_self();
mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
vm_size_t pagesize;
vm_statistics_data_t vm_stat;

host_page_size(host_port, &pagesize);
(void) host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size);
return vm_stat.free_count * pagesize;
}

EDIT1 - 函数 class_getInstanceSize为您提供对象实例的大小,但我从未尝试过,并且它可能不会取消引用 ivars 并汇总其用法。但也许它可以帮助你。

EDIT2 此函数为您提供 UIImage 的大小:

size_t sizeofUIImage(UIImage* image) {
return CGImageGetBytesPerRow(image.CGImage) * CGImageGetHeight(image.CGImage);
}

EDIT4 这是我的 1 秒计时器处理程序方法中的一些代码,它有助于在出现内存问题之前了解您的应用程序的运行情况。当然,可用内存会根据正在运行的后台任务(Safari、邮件等)而有所不同,而您对此没有太多控制权:

void logMemUsage(void) {
// compute memory usage and log if different by >= 100k
static long prevMemUsage = 0;
long curMemUsage = usedMemory();
long memUsageDiff = curMemUsage - prevMemUsage;

if (memUsageDiff > 100000 || memUsageDiff < -100000) {
prevMemUsage = curMemUsage;
NSLog(@"Memory used %7.1f (%+5.0f), free %7.1f kb",
curMemUsage/1000.0f, memUsageDiff/1000.0f, freeMemory()/1000.0f);
}
}

学分:源自 here 的内存释放/使用函数和 here .

关于iphone - UIImagePicker 的内存问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2921560/

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