Objective c 使用单例子类进行NSCoding

Objective c 使用单例子类进行NSCoding,objective-c,nscoding,Objective C,Nscoding,我有许多派生类,它们的公共基类符合NSCoding。我希望能够轻松地编码包含各种派生类实例的NSArray @interface Base : NSObject <NSCoding> @end @interface DerivedSingleton : Base +(instancetype) sharedInstance; @end @interface DerivedNonSingleton : Base @end 因此,如果我现在创建一个包含类实例的数组,并对其进行编码:

我有许多派生类,它们的公共基类符合
NSCoding
。我希望能够轻松地编码包含各种派生类实例的
NSArray

@interface Base : NSObject <NSCoding>
@end

@interface DerivedSingleton : Base
+(instancetype) sharedInstance;
@end

@interface DerivedNonSingleton : Base
@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
协议希望我为singleton实现
initWithCoder:
,但是在解码期间,我希望这个类提供共享实例,而不是一个新的
alloc
对象。

类似的东西应该可以工作

- (instancetype)initWithCoder:(NSCoder *)decoder
{
    self = [super init];

    return [self.class shared];
}

我会对singleton做类似的事情:

H
#导入
#pragma标记-接口
@接口SerializableSingleton:NSObject
#pragma标记类方法
#pragma标记-共享实例
+(instancetype)sharedInstance;
@结束
M
#导入“SerializableSingleton.h”
#pragma标记-参考
静态id_serializableSingletonSharedInstance=nil;
#pragma标记-实现
@实现SerializableSingleton
#pragma标记类方法
#pragma标记-共享实例
+(instancetype)sharedInstance{
@已同步([自类]){
if(_serializableSingletonSharedInstance==nil){
_serializableSingletonSharedInstance=[[[self class]alloc]init];
}
}
return _serializableSingletonSharedInstance;
}
#pragma标记-实例方法
#布拉格标记-
-(id)initWithCoder:(NSCoder*)aDecoder{
@已同步([自类]){
if(_serializableSingletonSharedInstance==nil){
if(self=[super init]){
//解码所需的数据。。。
}
_serializableSingletonSharedInstance=self;
}
}
return _serializableSingletonSharedInstance;
}
-(void)编码器与编码器:(NSCoder*)一个编码器{
//对所需数据进行编码
}
@结束

:-)我刚刚找到了Coder:和
的替换对象,在使用Coder:
之后,我醒了过来,并且实现了一个占位符对象…您的解决方案似乎更简单:-)是否值得加入一个
self=[super init]返回之前,是否已经设置好self.class?@Benjohn我想说添加
self=[super init]
,但我敢打赌
self.class
已经设置好了。谢谢Tom–过一会儿我会让你知道它是否有效:-)你好@holex,谢谢,但我不认为这能回答问题?问题在于,共享实例将与其他非单例对象(但派生自同一基类)位于一个数组中。整个阵列需要支持
NSCoding
。我特别想要存储的不是共享实例。当我解码这样一个数组存储时,任何共享单例引用都必须解码为对共享单例实例的引用。我对这些问题补充了很多–如果以前不清楚,很抱歉。@Benjohn,哦,我明白了。这是真的,在这种情况下,您需要在取消归档数组项后更新单例引用,但是您可以在返回
self
@Benjohn之前将这样的代码放入
-initWithCoder:
方法中,没有问题,我已经稍微更新了我的答案。完全不确定为什么会有投票来结束这个问题?如果你有这个要求,请你提供一个评论。非常感谢。
- (instancetype)initWithCoder:(NSCoder *)decoder
{
    self = [super init];

    return [self.class shared];
}
#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