【问题标题】:Saving extra data added to a class extension保存添加到类扩展的额外数据
【发布时间】:2012-05-02 10:14:09
【问题描述】:

我创建了一个 UIImage 类,它还包含应绘制图像的坐标数据:

#import "UIImageExtras.h"
#import <objc/runtime.h>

@implementation UIImage (Extras)

static char UII_ORIGINDATA_KEY;

@dynamic originData;

- (void)setOriginData:(NSValue *)originData {
    objc_setAssociatedObject(self, &UII_ORIGINDATA_KEY, originData, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSValue *)originData {
    return (NSValue *)objc_getAssociatedObject(self, &UII_ORIGINDATA_KEY);
}

到目前为止一切顺利。我有一个包含这些图像数组的类。该类称为 BookDoc,该数组称为插图。当我复制 BookDoc 的实例时,我复制了数组。我为每个图像定义的 originData 复制得很好。

但是,当我将这个新副本保存到文件时,我丢失了 originData。这是我的保存方法:

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

[self createDataPath];
NSString *illustrationsArrayPath = [_docPath stringByAppendingPathComponent:kIllustrationsFile];
BOOL result = [NSKeyedArchiver archiveRootObject:_illustrations toFile:illustrationsArrayPath];
if (!result)
    NSLog(@"Failed to archive array");

//This is not saving the originData. 

self.illustrations = nil;

}

我的问题是 - 如何确保保存每个图像的 originData?非常感谢。

更新:

好的,我已经在一个名为 UIImageExtra 的类中更改为 UIImage 的子类,并使其符合 NSCoding 如下:

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

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

现在当我保存包含这些 UIImageExtra 实例的插图数组时,它不应该自动保存原始数据吗?我保存数组的代码如下所示:

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

[self createDataPath];
NSString *illustrationsArrayPath = [_docPath stringByAppendingPathComponent:kIllustrationsFile];
BOOL result = [NSKeyedArchiver archiveRootObject:_illustrations toFile:illustrationsArrayPath];
if (!result)
    NSLog(@"Failed to archive array");

//This is not saving the originData. 

self.illustrations = nil;

}

【问题讨论】:

    标签: iphone objective-c ios nsarray nskeyedarchiver


    【解决方案1】:

    我认为你不能对通过关联对象 API 添加的属性执行此操作,因为 UIImageencodeWithCoder:initWithCoder: 不知道你的属性在那里。

    如果您可以通过继承 UIImage 来创建自定义 MyUiImage,那么您将能够覆盖您的类的 encodeWithCoder:initWithCoder:,并对您的属性以及 UIImage 进行编码/解码。

    【讨论】:

    • 哦,真可惜……使用继承并不方便。但我想这是有道理的,谢谢。
    • 如果您可以再看一下,我已经更新了我的答案?
    • @Smikey 您的更新应该可以工作。我假设您在子类中明确采用了&lt;NSCoding&gt; 协议,对吗?此外,您可能希望将 [super encodeWithCoder:aCoder]; 移动到其余代码之前,以与 Apple 的示例保持一致(但我认为在这种情况下并不重要)。
    • 是的,NSCoding。我将 NSLog 语句添加到 encodeWithCoder/initWithCoder 消息中,但它们从不打印。我尝试了: [self createDataPath]; NSString *illustrationsArrayPath = [_docPath stringByAppendingPathComponent:kIllustrationsFile]; NSMutableData *data = [[NSMutableData alloc] init]; NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; [archiver encodeObject:_illustrations forKey:kIllustrationDataKey]; [存档完成编码]; [data writeToFile:illustrationsArrayPath atomically: YES];
    • @Smikey 啊,我知道发生了什么。你可以在你的新类中定义一个类方法+(UIImageExtra*)imageNamed:,也可以覆盖-(id)imageWithContentsOfFile:+(UIImageExtra*)imageNamed: 会调用imageWithContentsOfFile:,后者会调用UIImageimageWithContentsOfFile:,然后设置您添加的额外字段。
    猜你喜欢
    • 1970-01-01
    • 2011-07-18
    • 1970-01-01
    • 2011-03-21
    • 2012-11-05
    • 1970-01-01
    • 2014-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多