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プロトコルに準拠していないため、このアプローチには問題があります。最初に行う必要があるのは、NSCodingをサポートするようにUIImageクラスを拡張することです。

NSCoding名前を付けて新しいカテゴリを追加し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

DeepCopy次に、UIImageViewと次のコードに(たとえば)名前の新しいカテゴリを追加します。

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

浅いコピー
オブジェクトをコピーする 1 つの方法は、浅いコピーです。このプロセスでは、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 に答える