2

我有一个对象 imageView1。我想创建另一个对象来保留 imageView1 的深层副本。像这样,

UIImageView *imageView1 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background.png"]];
UIImageView *imageView2 = [imageView1 copy];

我知道它不起作用,因为 UIImageView 不符合 NSCopying。但是我该怎么办?

4

2 回答 2

4

要创建 UIImageView 对象的深层副本,您需要使用 NSKeyedArchiver 将其归档,然后使用 NSKeyedUnarchiver 将其取消归档,但这种方法存在问题,因为 UIImage 不符合 NSCoding 协议。您首先需要做的是扩展 UIImage 类以支持 NSCoding。

添加一个名称为NSCodingon的新类别UIImage并放置以下代码:

UIImage+NSCoder.h

#import <UIKit/UIKit.h>

@interface UIImage (NSCoding)
- (id)initWithCoder:(NSCoder *)decoder;
- (void)encodeWithCoder:(NSCoder *)encoder;
@end

UIImage+NSCoder.m

#import "UIImage+NSCoder.h"

@implementation UIImage (NSCoding)
- (id)initWithCoder:(NSCoder *)decoder {
    NSData *pngData = [decoder decodeObjectForKey:@"PNGRepresentation"];
    [self autorelease];
    self = [[UIImage alloc] initWithData:pngData];
    return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:UIImagePNGRepresentation(self) forKey:@"PNGRepresentation"];
}

@end

然后在 UIImageView 和以下代码中添加一个名称DeepCopy为(例如)的新类别:

UIImageView+DeepCopy.h

#import <UIKit/UIKit.h>

@interface UIImageView (DeepCopy)
-(UIImageView *)deepCopy;
@end

UIImageView+DeepCopy.m

#import "UIImageView+DeepCopy.h"
#import "UIImage+NSCoder.h"

@implementation UIImageView (DeepCopy)

-(UIImageView *)deepCopy
{
    NSMutableData *data = [[NSMutableData alloc] init];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:self forKey:@"imageViewDeepCopy"];
    [archiver finishEncoding];
    [archiver release];

    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    UIImageView *imgView = [unarchiver decodeObjectForKey:@"imageViewDeepCopy"];
    [unarchiver release];
    [data release];

    return imgView;
}

@end

用法:导入你的 UIImageView+DeepCopy.h

UIImageView *imgView1 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"picture.jpg"]];
UIImageView *imageView2 = [imgView1 deepCopy];
于 2012-04-17T10:43:04.873 回答
4

浅复制
复制对象的一种方法是浅复制。在此过程中,B 与 A 连接到同一内存块。这也称为地址复制。这会导致 A 和 B 之间共享相同的数据,因此修改一个将改变另一个。现在不再从任何地方引用 B 的原始内存块。如果该语言没有自动垃圾回收,则 B 的原始内存块可能已泄漏。浅拷贝的优点是它们的执行速度快,并且不依赖于数据的大小。不是由整体块组成的对象的按位副本是浅副本。

深拷贝
另一种方法是深拷贝。这里的数据实际上是复制过来的。结果与浅拷贝给出的结果不同。优点是 A 和 B 不相互依赖,但代价是更慢更昂贵的副本。

在此处输入图像描述
因此,以下代码段将适用于您进行深度复制。

UIImageView *imageView1 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background.png"]];
UIImageView *imageView2 = [[UIImageView alloc] initWithImage:imageView1.image];
于 2012-04-17T10:45:54.543 回答