2

追加のプロパティとメソッドを含めたいので、UIImage (UIImageExtra) のサブクラスを作成しました。

このカスタム クラスのインスタンスを含む配列があります。ただし、配列を保存すると、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];
    }

それとも、このデータを間違った方法で保存しようとしているのでしょうか? どうもありがとう。

4

2 に答える 2

3

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

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

UIImage を返します。キャストしても、意図したとおりにはなりません。

UIImageExtra *scaledIllustration = [illustration adjustForResolution];

まだ単なるUIImageです。

これにアプローチする簡単で冗長な方法の 1 つは、UIImageExtra を UIImage のラッパーにすることです。ラッパーには、UIImage から初期化するためのクラス メソッドがあります。

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

そして、呼び出したいすべての UIImage メソッドは、ラップされた UIImage インスタンスに転送する必要があり-adjustForResolutionます。また、アンラップされた UIImage インスタンスにならないように、結果を再ラップするように注意してください。

より洗練された Objective-C のアプローチは、必要な機能をUIImageのカテゴリに追加し、メソッド スウィズリングを使用して NSCoding メソッドをカテゴリの実装に置き換えることです。カテゴリにインスタンス変数を追加できないため、(必要な Objective-C ランタイムの演習を除いて) ここで注意が必要なのは、「追加の」データを格納する場所です。[標準的な答えは、UIImage インスタンスの適切な表現 (ポインタ値を含む NSValue など) によってキー付けされたルックアサイド ディクショナリを持つことですが、ご想像のとおり、簿記はすぐに複雑になる可能性があります。]

少し話を戻して、新しい Cocoa プログラマーへの私のアドバイスは次のとおりです。たとえば、メソッドとメソッドを持つ(および NSCoding などを実装する)シンプルなImageValueクラスを作成し、そのインスタンスを配列に格納します。-image-extraInfo

于 2012-05-02T14:16:52.530 に答える
1

init 後に NSArray にオブジェクトを追加することはできません。NSMutableArray を使用してください。これが問題になる可能性があります。

于 2012-05-02T13:52:59.760 に答える