保存自定义对象的NSArray [英] Saving an NSArray of custom objects
问题描述
我已经创建了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屋!