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