制作UIImage的深层副本

Jus*_*zic 13 iphone memory-management objective-c

我的类包含一个UIImage属性,我想通过访问它的任何外部客户端强制它作为"复制"属性.但是,当我尝试在我的自定义setter中执行复制时,我得到关于UIImage不支持copyWithZone的运行时错误.那么,确保遵循正确的所有权政策的好方法是什么?

// declared in the interface as:
@property (nonatomic, readonly, copy) UIImage *personImage;

// class implementation
- (void)setPersonImage:(UIImage *)newImage
{
    if (newImage != personImage) 
    {
        [personImage release];

        // UIImage doesn't support copyWithZone
        personImage = [newImage copy];
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 14

这是一种方法:

UIImage *imageToCopy = <# Your image here #>;
UIGraphicsBeginImageContext(imageToCopy.size);
[imageToCopy drawInRect:CGRectMake(0, 0, imageToCopy.size.width, imageToCopy.size.height)];
UIImage *copiedImage = [UIGraphicsGetImageFromCurrentImageContext() retain];
UIGraphicsEndImageContext();   
Run Code Online (Sandbox Code Playgroud)

我需要这个的原因是我有一个用imageWithContentsOfFile:初始化的图像变量,我希望能够从磁盘中删除文件但保留图像变量.我很惊讶地发现,当文件被删除时,图像变量变得疯狂.它显示了古怪的随机数据,即使它在删除文件之前已初始化.当我深度复制时,它工作正常.


Jac*_*ues 1

为什么需要复制语义?UIImage 是不可变的,因此设置复制策略没有任何好处。如果存在其他人可能修改您的图像的风险,您只需要一个复制策略。由于 UIImage 是不可变的,因此不存在发生这种情况的风险,因此保留属性就可以了。

如果你多解释一下你想要做什么,可能还有其他方法可以实现它。

  • 我不确定OP是否有充分的理由,但复制 UIImage 的一个原因是它是否来自压缩文件格式。在需要之前它不会解压缩,如果将其应用到 UIImageView,解压缩将在 UI 线程上进行,这可能会很卡顿。复制强制解压到内存中。 (3认同)