Reputation: 346
I have an object imageView1. I want to create another object to keep the deep copy of imageView1. Like this,
UIImageView *imageView1 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background.png"]];
UIImageView *imageView2 = [imageView1 copy];
I know it does't work, because UIImageView doesn't conform to NSCopying. But how should i do?
Upvotes: 2
Views: 1262
Reputation: 15213
To create a deep copy of UIImageView object you need to archive it using NSKeyedArchiver and then unarchive it with NSKeyedUnarchiver, but there is a problem with this approach because UIImage does not conform to the NSCoding protocol. What you need to do first is to extend the UIImage class to support NSCoding.
Add a new category with name NSCoding
on UIImage
and place the following code:
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
Then add a new category with name DeepCopy
(for ex.) on UIImageView and the following code:
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
Usage: Import your UIImageView+DeepCopy.h
UIImageView *imgView1 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"picture.jpg"]];
UIImageView *imageView2 = [imgView1 deepCopy];
Upvotes: 4
Reputation: 5835
Shallow copy
One method of copying an object is the shallow copy. In this process, B is attached to the same memory block as A. This is otherwise known as address copy.
This results in a situation in which same data is shared between A and B, thus modifying the one will alter the other. The original memory block of B is now no longer referred to from anywhere. If the language does not have automatic garbage collection the original memory block of B has probably been leaked.
The advantage of shallow copies is that their execution speed is fast and does not depend on the size of the data.
Bitwise copies of objects which are not made up of a monolithic block are shallow copies.
Deep copy
An alternative is a deep copy. Here the data is actually copied over. The result is different from the result a shallow copy gives. The advantage is that A and B do not depend on each other but at the cost of a slower more expensive copy.
So following snippet will work for you to do deep copy.
UIImageView *imageView1 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background.png"]];
UIImageView *imageView2 = [[UIImageView alloc] initWithImage:imageView1.image];
Upvotes: 4