我一直在尝试用UIImagePickerController
来减少内存占用,但我开始认为我遇到的内存问题是由于内存管理不善导致的,而不是处理{{{ 1}}对象。
我的工作流程是:单击“编辑图像”按钮,显示UIImagePickerController
。此操作表允许您删除,拍照,从库中选择或取消。如果您选择从库中选择或拍照,我会UIActionSheet
alloc
的实例并显示它,然后发布UIImagePickerController
:
UIImagePickerController
一旦我从-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (actionSheet.tag != 999) {
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
BOOL pickImage = nil;
if (actionSheet.tag == iPhoneWithDelete) {
switch (buttonIndex) {
case 0:
object.objectImage = nil;
pickImage = NO;
break;
case 1:
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
pickImage = YES;
break;
case 2:
imagePicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
pickImage = YES;
break;
default:
pickImage = NO;
break;
}
} else if (actionSheet.tag == iPhoneNoDelete) {
switch (buttonIndex) {
case 0:
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
pickImage = YES;
break;
case 1:
imagePicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
pickImage = YES;
break;
default:
pickImage = NO;
break;
}
} else if (actionSheet.tag == iPodWithDelete) {
switch (buttonIndex) {
case 0:
object.objectImage = nil;
pickImage = NO;
break;
case 1:
imagePicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
pickImage = YES;
break;
default:
pickImage = NO;
break;
}
} else if (actionSheet.tag == iPodNoDelete) {
switch (buttonIndex) {
case 0:
imagePicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
pickImage = YES;
break;
default:
pickImage = NO;
break;
}
}
if (pickImage) {
imagePicker.allowsEditing = YES;
[self presentModalViewController:imagePicker animated:YES];
} else {
[self setupImageButton];
[self setupChooseImageButton];
}
[imagePicker release];
}
}
获得选择,我保存了2张图片,用于缩略图的已编辑图像的调整版本,以及原始未编辑图像的800x600版本为关系属性(Transformational) ,使用Recipes演示代码中的相同UIImage到PNG转换进行显示使用:(调整大小的方法基于this SO post中演示的方法。)
UIImagePickerController
当我通过- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[self dismissModalViewControllerAnimated:YES];
NSManagedObject *oldImage = object.imageFull;
if (oldImage != nil)
{
[object.managedObjectContext deleteObject:oldImage];
}
NSManagedObject *image = [NSEntityDescription insertNewObjectForEntityForName:@"Image" inManagedObjectContext:object.managedObjectContext];
object.imageFull = image;
UIImage *rawImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
CGSize size = CGSizeMake(800, 600);
UIImage *fullImage = [UIImageManipulator scaleImage:rawImage toSize:size];
[image setValue:fullImage forKey:@"imageFull"];
UIImage *processedImage = [UIImageManipulator scaleImage:[info objectForKey:@"UIImagePickerControllerEditedImage"] toSize:CGSizeMake(75, 75)];
object.objectImage = processedImage;
[self setupImageButton];
[self setupChooseImageButton];
rawImage = nil;
fullImage = nil;
processedImage = nil;
}
时,我会在viewDidUnload
期间设置self.object = nil
和[object release]
,但在大约10次图像更改后,我仍然会收到内存警告在20左右崩溃。这让我相信我没有以正确的方式获得完整的图像。我在这里缺少什么?
在第二个注意事项中,相机来源是否比相册来源使用更多的内存?使用相机时,我会更容易崩溃。
为任何有关我可能处理错误的信息启动赏金。我将更新这篇文章,并对我不清楚的任何答案进行更新。就在我的智慧结束时。
重新编写代码以考虑chrissr的建议,并实施dealloc
以提高可用性。这个过程有效吗?仍然会收到内存警告,以及大约20张图像的崩溃。我确信执行昂贵的GCD
调整大小和使用UIImage
的组合正在谋杀CPU,但我无法想象每个应用程序处理UIImagePickerController
周围的不确定性。我的记忆足迹大约是2兆。我一直在假设这是一个很大的开销。我应该进一步减少这个足迹吗?
以下是修改后的代码:
UIImagePickerController
答案 0 :(得分:2)
处理UIImagePickerController时,内存警告非常常见。使用相机时尤其如此。请记住,虽然磁盘上的JPG或PNG可能只有几MB,但用于绘制图像的未压缩内存位图使用的内容要多得多。
没有什么是你必须做错的,但可以做一些改进:
为什么不将图像写入磁盘并将数据路径存储到数据库中,而不是将图像字节存储在核心数据中?
您是否可以找到直接管理其生命周期并尽快发布的方法,而不是使用如此多的自动释放图像?
您最好的选择可能是在处理后尽快将图像写入磁盘并释放他们正在使用的内存。然后使用Core Data而不是原始数据存储它们的位置。