2011年3月10日木曜日

UIImageViewとNSCoding

NSCodingを使って独自Classを保存しようとしたらエラーに。

↓クラスはこんな感じのクラス
-------------------------------------------------
#import <Foundation/Foundation.h>

@interface ArchiveObject : NSObject <NSCoding> {
    NSString *string01;
    UIImageView *imageView;   
}

@property (nonatomic, retain) NSString *string01;
@property (nonatomic, retain) UIImageView *imageView;

@end
-------------------------------------------------
もちろん

- (void)encodeWithCoder:(NSCoder*)coder
- (id)initWithCoder:(NSCoder*)coder

は実装してますよ、はい。

まぁ、このクラスをエンコードしようとすると、
以下のエラーが

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIImage encodeWithCoder:]: unrecognized selector sent to instance xxxxxx'

ふーん。。。。。
って、え?UIImageってNSCoding実装してないのかよ!
んなわけないだろって思いつつ、UIImage.hをみてみると

@interface UIImage : NSObject {

。。。。ガボーン

悩みました。


要は
@interface UIImage : NSObject <NSCoding> {
こうなって欲しいんですよ。(もちろんメソッドも実装するとして)

で、閃きました。

カテゴリや!

なんか昔に
UIImage+crop.h
みたいなクラス見た事ある!

カテゴリに関しての詳細はググッてください。

というわけで、UIImageにNSCodingの機能を追加したクラスを作成

UIImage+NSCoding.h
-------------------------------------------------
#import <Foundation/Foundation.h>

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


UIImage+NSCoding.m
-------------------------------------------------
#import "UIImage+NSCoding.h"

@implementation UIImage(NSCoding)

- (id)initWithCoder:(NSCoder *)decoder {
    if ((self = [super init])) {
        NSData *data = [decoder decodeObjectForKey:@"UIImage"];
        self = [self initWithData:data];
    }
  
    return self;
}

- (void)encodeWithCoder:(NSCoder *)encoder {
    NSData *data = UIImagePNGRepresentation(self);
    [encoder encodeObject:data forKey:@"UIImage"];
}

@end

これで、UIImageにNSCodingの実装を追加できました。
おしまい。

あとはこんな感じかな(結構適当)
エンコード、デコードするだけ

- (IBAction)save {
    ArchiveObject *object = [[ArchiveObject alloc] init];
    object.string01 = @"hoge";
    object.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"hoge.png"]];
   
    NSString *dataPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/data.dat"];
    [NSKeyedArchiver archiveRootObject:object toFile:dataPath];
}

- (IBAction)load {
    NSString *dataPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/data.dat"];
    ArchiveObject *loadData = [NSKeyedUnarchiver unarchiveObjectWithFile:dataPath];
   
    loadDataからゴニョゴニョ。。。。
    localImageView.image = loadData.imageView.image; とか
}


とりあえず、UIImageViewを含む独自クラスのエンコード/デコードに成功しました。



0 件のコメント:

コメントを投稿