保存自定义对象的NSArray [英] Saving an NSArray of custom objects

查看:98
本文介绍了保存自定义对象的NSArray的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了UIImage(UIImageExtra)的子类,因为我想包含额外的属性和方法。

I've created a subclass of UIImage (UIImageExtra) as I want to include extra properties and methods.

我有一个包含这个自定义类的实例的数组。但是当我保存数组时,似乎没有保存UIImageExtra类中的额外数据。

I have an array that contains instances of this custom class.However when I save the array, it appears the extra data in the UIImageExtra class is not saved.

UIImageExtra符合NSCoding,但是没有调用initWithCoder或encodeWithCoder,因为我添加的NSLog语句没有打印。

UIImageExtra conforms to NSCoding, but neither initWithCoder or encodeWithCoder are called, as NSLog statements I've added aren't printed.

我保存数组的方法如下所示:

My method to save the array looks like this:

- (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具有以下用于保存的委托方法:

And the UIImageExtra has the following delegate methods for saving:

    #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;
}

我首先创建数组的代码如下所示(以防万一)提供任何线索)

My code to create the array in the first place looks like this (in case that offers any clues)

        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];
    }

或者我只是想以错误的方式保存这些数据?非常感谢。

Or am I just going about saving this data the wrong way? Many thanks.

推荐答案

初始化数组的代码实际上并没有创建UIImageExtra子类的实例。

Your code to initialize the array is not actually creating instances of your UIImageExtra subclass.

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

返回UIImage。投射它并不能达到您的目的。

returns a UIImage. Casting it doesn't do what you were intending.

UIImageExtra *scaledIllustration = [illustration adjustForResolution];

只是一个UIImage。

is still just a UIImage.

一种直接但又详细的方法是在UIImage周围使UIImageExtra成为包装器。包装器将有一个用于从UIImage初始化的类方法:

One straightforward-but-verbose way to approach this would be to make UIImageExtra a wrapper around UIImage. The wrapper would have a class method for initializing from a UIImage:

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

然后你要调用的每个UIImage方法都必须转发到包装的UIImage实例 - 也小心重新包装例如的结果 -adjustForResolution 以免你最终得到一个解包的UIImage实例。

And then every UIImage method you want to call would have to forward to the wrapped UIImage instance-- also being careful to re-wrap the result of e.g. -adjustForResolution lest you again end up with an unwrapped UIImage instance.

一个更客观的C复杂方法是在UIImage上的 Category 中添加所需的功能,然后使用方法调配将NSCoding方法替换为您的类别实现。这个棘手的部分(除了所需的Objective-C运行时体操)是存储额外数据的地方,因为您无法在类别中添加实例变量。 [标准答案是有一个由UIImage实例的某个合适表示键入的后备字典(如包含其指针值的NSValue),但正如您可以想象的那样,簿记可以快速复杂化。]

A more Objective-C sophisticated approach would be to add the functionality you want in a Category on UIImage, and then use method swizzling to replace the NSCoding methods with your category implementations. The tricky part of this (apart from the required Objective-C runtime gymnastics) is where to store your "extra" data, since you can't add instance variables in a category. [The standard answer is to have a look-aside dictionary keyed by some suitable representation of the UIImage instance (like an NSValue containing its pointer value), but as you can imagine the bookkeeping can get complicated fast.]

稍微退一步,我对一位新Cocoa程序员的建议是:想想一个更简单的方法。如果你想要做的事情很复杂,那就别管其他了。例如,编写一个简单的 ImageValue 类,它具有 -image 方法和 -extraInfo 方法(并实现NSCoding等),并在数组中存储该实例。

Stepping back for a moment, my advice to a new Cocoa programmer would be: "Think of a simpler way. If what you are trying to do is this complicated, try something else." For example, write a simple ImageValue class that has an -image method and an -extraInfo method (and implements NSCoding, etc.), and store instances of that in your array.

这篇关于保存自定义对象的NSArray的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆