2012-05-02 5 views
2

余分なプロパティとメソッドを追加したいので、UIImage(UIImageExtra)のサブクラスを作成しました。カスタムオブジェクトのNSArrayを保存する

私はこのカスタムクラスのインスタンスを含む配列を持っています。しかし、配列を保存すると、UIImageExtraクラスの余分なデータは保存されません。

UIImageExtraはNSCodingに準拠していますが、追加したNSLogステートメントは印刷されないため、initWithCoderもencodeWithCoderも呼び出されません。

配列を保存する私の方法は次のようになります。

- (void)saveIllustrations { 
if (_illustrations == nil) { 
    NSLog(@"Nil array"); 
    return; 
} 

[self createDataPath]; 
//Serialize the data and write to disk 
NSString *illustrationsArrayPath = [_docPath stringByAppendingPathComponent:kIllustrationsFile]; 
NSMutableData *data = [[NSMutableData alloc] init]; 
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; 
[archiver encodeObject:_illustrations forKey:kIllustrationDataKey]; 
[archiver finishEncoding]; 
[data writeToFile:illustrationsArrayPath atomically: YES]; 
} 

そしてUIImageExtraを保存するために、次のデリゲートメソッドがあります。

#pragma mark - NSCoding 

- (void)encodeWithCoder:(NSCoder *)aCoder { 
    NSLog(@"Encoding origin data!"); 
    [super encodeWithCoder:aCoder]; 
    [aCoder encodeObject:originData forKey:kOriginData]; 
} 

- (id)initWithCoder:(NSCoder *)aDecoder { 
    if (self = [super initWithCoder:(NSCoder *) aDecoder]) { 
     NSLog(@"Decoding origin data"); 
     self.originData = [aDecoder decodeObjectForKey:kOriginData]; 
    } 
    return self; 
} 

最初の場所のルックスに配列を作成するために私のコードこのように(手がかりを提供する場合)

 for (NSDictionary *illustrationDict in illustrationDicts) { 
     NSString *illustrationString = [illustrationDict objectForKey:@"Filename"]; 
     NSNumber *xCoord = [illustrationDict objectForKey:@"xCoord"]; 
     NSNumber *yCoord = [illustrationDict objectForKey:@"yCoord"]; 
     UIImageExtra *illustration = (UIImageExtra *)[UIImage imageNamed:illustrationString]; 

     //Scale the illustration to size it for different devices 
     UIImageExtra *scaledIllustration = [illustration adjustForResolution]; 
     NSValue *originData = [NSValue valueWithCGPoint:CGPointMake([xCoord intValue], [yCoord intValue])]; 
     [scaledIllustration setOriginData:originData]; 
     [self.illustrations addObject:scaledIllustration]; 
    } 

このデータを間違った方法で入力しますか?どうもありがとう。

答えて

3

配列を初期化するコードは、実際にはUIImageExtraサブクラスのインスタンスを作成していません。

UIImageExtra *illustration = (UIImageExtra *)[UIImage imageNamed:illustrationString]; 

は、UIImageを返します。それをキャストすることは、あなたが意図していたことをしません。

UIImageExtra *scaledIllustration = [illustration adjustForResolution]; 

まだちょうどUIImage です。

これに近づける簡単な方法は、UIImageExtraをUIImageのラッパーラッパーにすることです。ラッパーはUIImageから初期化するためのクラスメソッド必要があります:

+ (UIImageExtra)imageExtraWithUIImage:(UIImage *)image; 

をそしてあなたが呼び出したいすべてのUIImageの方法はまた、再ラップ結果のように注意してくださいinstance--包まUIImageに転送する必要があります例えば-adjustForResolutionあなたがラップされていないUIImageインスタンスで終わることはもうありません。

よりObjective-Cの洗練されたアプローチは、あなたがUIImage上カテゴリーに必要な機能を追加し、あなたのカテゴリ実装とNSCodingのメソッドを置き換えるために方法スウィズリングを使用することです。このような難しい部分(Objective-C実行時体操とは別)は、カテゴリ内にインスタンス変数を追加できないため、「余分な」データを格納する場所です。 [標準的な答えは、(ポインタ値を含むNSValueのような)UIImageインスタンスの適切な表現によってキーイングされた見た目の辞書を持つことですが、帳簿管理が複雑になることが想像されるように複雑です。]

ステッピングバックしばらくの間、新しいCocoaプログラマーへの私のアドバイスは、「もっと簡単な方法を考えてください。もしあなたがしようとしていることが複雑なら、何か他のことを試してみてください。たとえば、-imageメソッドと-extraInfoメソッドを持ち(NSCodingなどを実装する)単純なImageValueクラスを作成し、そのインスタンスを配列に格納します。

+0

+(UIImageExtra *)imageExtraWithUIImage:(UIImage *)image; UIImageの議論で私は何をしますか?私はallocとinitを使って新しいUIImageExtraオブジェクトを作成して返すと仮定していますが、UIImageを新たに割り当てられたUIImageExtraのプロパティとして設定する必要がありますか?どの場合、サブクラスにUIImageのインスタンスを定義する必要がありますか?サブクラスのプロパティとして親クラスのインスタンスを持つのは変ですか?または、何とか親クラスをUIImageのインスタンスに設定することはできますか? – Smikey

1

initの後にNSArrayにオブジェクトを追加することはできません。問題の可能性があるNSMutableArrayを使用します。

関連する問題