Iphone 如何在UIKit中实现类的深度复制?

Iphone 如何在UIKit中实现类的深度复制?,iphone,objective-c,ios,deep-copy,Iphone,Objective C,Ios,Deep Copy,我有一个对象imageView1。我想创建另一个对象以保留imageView1的深度副本。 像这样, UIImageView *imageView1 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background.png"]]; UIImageView *imageView2 = [imageView1 copy]; 我知道它不起作用,因为UIImageView不符合NSCopying。但我们应该怎么做呢 是吗?要创建

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

UIImageView *imageView1 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background.png"]];
UIImageView *imageView2 = [imageView1 copy];
我知道它不起作用,因为UIImageView不符合NSCopying。但我们应该怎么做呢
是吗?

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

UIImage
上添加一个名为
NSCoding
的新类别,并放置以下代码:

UIImage+NSCoder.h

#import <UIKit/UIKit.h>

@interface UIImage (NSCoding)
- (id)initWithCoder:(NSCoder *)decoder;
- (void)encodeWithCoder:(NSCoder *)encoder;
@end
#import <UIKit/UIKit.h>

@interface UIImageView (DeepCopy)
-(UIImageView *)deepCopy;
@end
然后在UIImageView上添加一个名为
DeepCopy
(例如)的新类别,并添加以下代码:

UIImageView+DeepCopy.h

#import <UIKit/UIKit.h>

@interface UIImage (NSCoding)
- (id)initWithCoder:(NSCoder *)decoder;
- (void)encodeWithCoder:(NSCoder *)encoder;
@end
#import <UIKit/UIKit.h>

@interface UIImageView (DeepCopy)
-(UIImageView *)deepCopy;
@end
用法: 导入UIImageView+DeepCopy.h

UIImageView *imgView1 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"picture.jpg"]];
UIImageView *imageView2 = [imgView1 deepCopy];

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

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


所以下面的代码片段可以帮助您进行深度复制

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

复制UI组件在任何体系结构中都不是一个好主意。@Sulthan我理解你的意思。但是,我确实需要UIImageView来保存一些关于模型的数据。当然,它可以用于存储CGRect、文件名等。我认为这比直接使用UIImageView复杂。谢谢你的经验。我会处理的。你应该能够从你的模型中创建UI,而不是让UI成为你模型的一部分。我已经尝试过了。但是,我发现imageView2.image是imageView1.image的引用。这两个映像具有相同的内存地址。此外,imageView1可能有一些子视图。@tzzzoz,所以代码不做深度复制,对吗?对于这些UIImage对象,我认为它不做深度复制。你可以试试看这两个UIImage对象是否有相同的内存地址。它非常聪明!但是,如果我在imageView1中有一些子ImageView。如何修改此方法?此方法将复制整个对象图,因此无需更改任何内容。UIImageView*imgView1=[[UIImageView alloc]initWithImage:[UIIMAGENAME:@“picture.jpg”];UIImageView*imgView2=[[UIImageView alloc]initWithImage:[UIImageName:@“picture2.jpg”];[imgView1添加子视图:imgView2];UIImageView*copiedResult=[imgView1 deepCopy];