序列化包含 类 未实现 NSCoding 的 NSMutableArray

Serialize a NSMutableArray that includes classes not implementing NSCoding

我需要将 NSMutableArray 保存到磁盘以存储我的应用程序数据。我知道那里有很多类似的问题,但我发现其中 none 个涵盖了我的问题。

我不想为了节省一个 NSMutableArray 而集成 Core Data。通常我会去实施 NSCoding 协议并使用 NSKeyedUnarchiver。不幸的是,我的数据模型 class 有一些来自库的外来 classes,它们没有实现 NSCoding 协议。

那么我存储数组的最佳方式是什么?

这是我尝试过的方法,但由于给定的原因,它不起作用:

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <ForeignFramework/ForeignFramework.h>

@interface DEModelClass : NSObject <NSCoding>

@property (nonatomic,strong) ForeignFramework *foreignFramework;
@property (nonatomic,strong) UIImage *image;
@property (nonatomic,copy) NSNumber *number1;
@property (nonatomic,copy) NSNumber *number2;

@end


#define kEncodeKeyForeign   @"kEncodeKeyForeign"
#define kEncodeKeyImage      @"kEncodeKeyImage"
#define kEncodeKeyNumber1     @"kEncodeKeyNumber1"
#define kEncodeKeyNumber2     @"kEncodeKeyNumber2"


#pragma mark - NSCoding
- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:self.foreignFramework   forKey:kEncodeKey];
    [aCoder encodeObject:self.image  forKey:kEncodeKeyImage];
    [aCoder encodeObject:self.number1 forKey:kEncodeKeyNumber1];
    [aCoder encodeObject:self.number2 forKey:kEncodeKeyNumber2];

}

- (id)initWithCoder:(NSCoder *)aDecoder {
    if ((self = [super init]))
    {
        self.foreignFramework = [aDecoder decodeObjectForKey:kEncodeKeyForeign];
        self.image    = [aDecoder decodeObjectForKey:kEncodeKeyImage];
        self.number1   = [aDecoder decodeObjectForKey:kEncodeKeyNumber1];
        self.number2   = [aDecoder decodeObjectForKey:kEncodeKeyNumber2];

    }
    return self;
}

你应该使用NSCoding协议,你可以使用它。

一个。我假设您知道要存储外部 类 的哪些属性。 (可能是让您在加载时重新实例化实例对象的数据。)如果不是,则无法存储它们。当然,Cocoa、NSArray、$whatever 都不知道。这些是通用的。

乙。当您完成选择要存储的属性后,只需将一个类别添加到为您完成工作的外部 类:

@interface ForeignClass (MyCodingAddition)
- (void)encodeWithCoder:(NSCoder*)encoder;
- (id)initWithCoder:(NSCoder*)decoder;
@end

@implementation ForeignClass (MyCodingAddition)
- (void)encodeWithCoder:(NSCoder*)encoder
{
  [coder encodeObject:self.property withKey:…]
  …
}

- (id)initWithCoder:(NSCoder*)decoder
{
  self = [super init];
  if (self)
  {
    self.property = [decode objectForKey:…];
    …
  }
  return self;
}
@end