我有许多派生类,它们的公共基类符合NSCoding
。我希望能够轻松编码各种派生类的NSArray
持有实例。
@interface Base : NSObject <NSCoding>
@end
@interface DerivedSingleton : Base
+(instancetype) sharedInstance;
@end
@interface DerivedNonSingleton : Base
@end
派生单例在运行系统中应该只有一个实例。它实际上没有任何状态可以在编码器中编码。它的实例是使用+(void) initialize
类方法创建的。
DerivedSingleton *sharedInstance;
@implementation DerivedSingleton
+(void) initialize
{
sharedInstance = [DerivedSingleton new];
}
+(instancetype) sharedInstance
{
return sharedInstance;
}
@end
所以,如果我现在创建一个包含类实例的数组,并对其进行编码:
NSArray *const array = @[
[DerivedSingleton sharedInstance],
[DerivedNonSingleton new],
[DerivedNonSingleton new]];
NSData *const arrayData = [NSKeyedArchiver archivedDataWithRootObject: array];
当我稍后解码它时,我需要引用共享单例来解码为共享单例的引用...
NSArray *const decodedArray = [NSKeyedUnarchiver unarchiveObjectWithData: arrayData];
[decodedArray objectAtIndex: 0] == [DerivedSingleton sharedInstance];
我注意到NSCoding
协议要求我为单例实现initWithCoder:
,但在解码期间,我希望此类提供共享实例,而不是新的alloc
ed对象
答案 0 :(得分:1)
这样的事情应该有效
- (instancetype)initWithCoder:(NSCoder *)decoder
{
self = [super init];
return [self.class shared];
}
答案 1 :(得分:0)
我会用单身人士做类似的事情:
#import <Foundation/Foundation.h>
#pragma mark - Interface
@interface SerializableSingleton : NSObject <NSCoding>
#pragma mark - Class methods
#pragma mark - Shared instance
+ (instancetype)sharedInstance;
@end
#import "SerializableSingleton.h"
#pragma mark - Reference
static id _serializableSingletonSharedInstance = nil;
#pragma mark - Implementation
@implementation SerializableSingleton
#pragma mark - Class methods
#pragma mark - Shared instance
+ (instancetype)sharedInstance {
@synchronized([self class]) {
if (_serializableSingletonSharedInstance == nil) {
_serializableSingletonSharedInstance = [[[self class] alloc] init];
}
}
return _serializableSingletonSharedInstance;
}
#pragma mark - Instance methods
#pragma mark - <NSCoding>
- (id)initWithCoder:(NSCoder *)aDecoder {
@synchronized([self class]) {
if (_serializableSingletonSharedInstance == nil) {
if (self = [super init]) {
// decode the desired data...
}
_serializableSingletonSharedInstance = self;
}
}
return _serializableSingletonSharedInstance;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
// encode the desired data
}
@end