【问题标题】:iPhone Memory Management with UIImage使用 UIImage 进行 iPhone 内存管理
【发布时间】:2009-04-24 14:12:31
【问题描述】:
- (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 上崩溃了。创建图像时我应该采取其他方法吗?

【问题讨论】:

    标签: iphone memory-management memory-leaks uiimage


    【解决方案1】:

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

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

    【讨论】:

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

    仪器显示对象确实被释放但内存不断增加?是不是说释放对象不一定释放内存?

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

    如果有其他东西在使用你的 UIImage,它不会被释放,这可能是你的代码或者你在 Interface builder 中创建的视图。

    有可能你调用的保留太主要了,因此引用计数器永远不会达到零。

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

    【讨论】:

      猜你喜欢
      • 2011-06-06
      • 1970-01-01
      • 2010-09-30
      • 1970-01-01
      • 1970-01-01
      • 2011-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多