使用UIImage进行iPhone内存管理

时间:2009-04-24 14:12:32

标签: iphone memory-management memory-leaks uiimage

- (void)imagePickerController:(UIImagePickerController *)picker 
        didFinishPickingImage:(UIImage *)image 
                  editingInfo:(NSDictionary *)editingInfo {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [self.pickerTrigger setImage:image];
    [self.button setTitle:@" " forState:UIControlStateNormal];
    [self.button setTitle:@" " forState:UIControlStateSelected];
    [self.button setTitle:@" " forState:UIControlStateHighlighted];

    CGSize oldSize = [image size];
    CGFloat width = oldSize.width;
    CGFloat height = oldSize.height;
    CGSize targetSize = CGSizeMake(320.0, 400.0);
    CGFloat targetWidth = targetSize.width;
    CGFloat targetHeight = targetSize.height;
    CGFloat scaleFactor = 0.0;
    CGFloat scaledWidth = targetWidth;
    CGFloat scaledHeight = targetHeight;
    CGPoint thumbnailPoint = CGPointMake(0.0,0.0);

    if (CGSizeEqualToSize(oldSize, targetSize) == NO)
    {
        CGFloat widthFactor = targetWidth / width;
        CGFloat heightFactor = targetHeight / height;

        if (widthFactor > heightFactor)
            scaleFactor = widthFactor;
        else
            scaleFactor = heightFactor;
        scaledWidth = width * scaleFactor;
        scaledHeight = height * scaleFactor;

        if (widthFactor > heightFactor)
            thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
        else if (widthFactor < heightFactor)
            thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
    }

    UIGraphicsBeginImageContext(targetSize);

    CGRect thumbnailRect = CGRectZero;
    thumbnailRect.origin = thumbnailPoint;
    thumbnailRect.size.width = scaledWidth;
    thumbnailRect.size.height = scaledHeight;
    [image drawInRect:thumbnailRect];

    self.selectedImage = UIGraphicsGetImageFromCurrentImageContext();

    NSLog([NSString stringWithFormat:@"After getting from DB %d", [selectedImage retainCount]]);
    UIGraphicsEndImageContext();
    [pool release];
    [picker dismissModalViewControllerAnimated:YES];
}

变量selectedImage已在接口文件中声明为保留属性。 你可以猜到我缩略图像将它存储在selectedImage中。然后我在另一个函数中重用它并在dealloc函数中释放它。

仪器显示对象确实被释放但内存不断增加?这是否意味着释放对象不一定会释放内存?

我经常使用UIImages面对这种事情吗?任何猜测?

我已将[selectedImage release]添加到(void)dealloc函数中,该函数被调用,保留计数变为零并且对象确实被释放。但是分配了一些内存(我相信使用UIGraphicsGetImageFromCurrentImageContext();我猜)它没有被释放。我添加了4-5个图像,在模拟器中内存达到了惊人的117 MB,然后它在模拟器中降回到48 MB。但该应用程序在iPhone上崩溃了。我应该在创建图像时采取其他方法吗?

2 个答案:

答案 0 :(得分:0)

如果您已将selectedImage声明为“保留属性”,则必须向其发送消息以将其释放。

这是因为图像保留在setter的隐式调用中: self.selectedImage = XXX 。您无法看到它,因为它在编译器为属性设置器创建的代码中。

答案 1 :(得分:0)

  

仪器显示对象确实被释放但内存不断增加?这是否意味着释放对象不一定会释放内存?

当你释放一个对象时,它会将它的ref计数器减1,只有当该计数器达到零时它才会从内存中释放。

如果其他人正在使用它,您的UIImage将不会被释放,这可能是您在“界面”构建器中创建的代码或视图。

你可能会调用retain太大的时间,因此ref计数器永远不会达到零。

另外,请记住,在iPhone上的每个事件循环开始时,都会创建一个自动释放池。您始终可以将对象添加到该对象并自动清理它。