计划的NSDictionary子类的替代方案是singleton

时间:2012-03-15 02:09:00

标签: objective-c collections singleton nsdictionary subclassing

我已经成功创建了一个NSDictionary子类,一个单例,用于保存一组线索和答案。我看到一些奇怪的行为,我追溯到这样一个事实,即子类化NSDictionary实际上导致了NSCFDictionary,所以我计划使用的NSDictionary方法不起作用,除非我写它们。我在另外两个SO问题中找到了一些有用的东西:herehere。我看到可能会有一些解决方法,但它们也有问题。

我正在为测试目的对一些示例线索和答案进行硬编码,目的是稍后转向某种核心数据方法。我很确定继续我目前的方法将是很多用于测试目的的工作。这些是我正在考虑的选择;有什么建议吗?

  1. 删除临时字典单例方法并将其替换为一些或多或少模仿字典以进行测试的数组?
  2. 切换到NSMutableDictionary,即使我不打算改变?可变版本看起来可能更容易进行子类化,但我不确定。
  3. 转到某种全局常量数组并跳过单例方法进行测试(我希望这些是正确的术语)。
  4. 写下/骑过所需的方法?
  5. 咬紧牙关,找出应用的核心数据部分?
  6. 别的什么?

2 个答案:

答案 0 :(得分:4)

为了避免子类化NSDictionary的麻烦,我会使用一个单独的单例对象,它使用组合来拥有一个NSDictionary。这是否有效取决于你希望用这个单身人士做什么。

有关各种Objective-C单例选项的讨论,请参阅What should my Objective-C singleton look like?

答案 1 :(得分:3)

需要子类化Foundation框架提供的任何集合类(NSArray,NSDictionary,NSSet,NSMapTable等及其可变变体)是不常见的。事实上,如果您认为自己需要这样做,那么您的第一步应该是仔细考虑为什么需要这样做,然后再睡上它。 (如果你想看到有人对它进行了研究,请查看Mike Ash's recent article on reimplementing NSMutableArray。)将集合类子类化如此不寻常的原因是集合类已经实现了标准数据结构所需的行为表示:NSArray为您提供索引的对象列表; NSDictionary为您提供了一个关联数组;等等。

根据您的评论,听起来您可能会受到某些容器组合的良好服务。很难从描述中确切地说出你想要的东西,所以我必须做出一些假设(我会试着说明),并希望即使它们错了,你仍然可能指向正确的方向。所以,让我们说你有一个问题列表,对于每个问题你都有答案和一些线索。在这种情况下,您可以选择使用字典来表示每个问题。字典可以有三个键:'问题','回答'和'线索'。与前两个键关联的值可能只是字符串,'clues'的值可能是一个数组或一组字符串。既然你有一些问题,你就可以将每个字典存储在一个共同的数组中。在JSON格式中,它看起来像这样:

[
    {
        "question" : "What's the capitol of New York?",
        "answer" : "Albany",
        "clues" : 
            [
                "It's not New York City.",
                "It's near the Hudson river.",
                "Its name begins with 'A'."
            ]
    },
    {
        "question" : "What's the state sport of Maryland?",
        "answer" : "jousting",
        "clues" : 
            [
                "If you try it, you'll need a horse and some armor.",
                "Kids, don't try this at home."
            ]
    }
]

如果您愿意,可以通过编程方式构建它,但由于它只是静态数据,因此您最好使用属性列表编辑器来创建数据。然后,您可以使用+arrayWithContentsOfFile:将其读入数组。

现在,关于那个单身人士...听起来你真的只是想要一个能保存你的数据并且易于访问的对象。因此,创建一个可以包含上述数组的类:

@interface QAModel : NSObject
@property (strong) NSArray *questions;

+ (QAModel*)sharedModel

@end

@implementation QAModel
@synthesize questions = _questions;

+ (QAModel*)sharedModel
{
    if (self.sharedModel == nil) {
        sharedModel = [[QAModel alloc] init];
    }
    return sharedModel;
}

- (id)init
{
    if ((self = [super init])) {
        _questions = [NSArray arrayWithContentsOfFile:pathToMyDataFile];
    }
    return self;
}
@end

这为您提供了一个易于访问的共享模型对象。它不是一个真正的单身人士,因为如果你真的想要它不会阻止你多次实例化它,但这通常不是人们在谈论使用单身时所追求的。

请注意,这里唯一的子类是NSObject的简单子类 - 数组和字典就是现成的。