【问题标题】:Alternatives to planned NSDictionary subclass that is singleton计划的 NSDictionary 单例子类的替代方案
【发布时间】:2012-03-15 02:08:59
【问题描述】:

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

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

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

【问题讨论】:

  • 您真正想要完成什么?这个单例的目的是什么?出于对 Apple 一切事物的热爱,您为什么要尝试继承 NSDictionary?
  • 目的在第一句。字典曾经并且确实包含一系列线索和一系列答案。为什么?好吧,我边走边学,坦率地说,我仍然没有看到任何你不应该这样做的真正线索:建议x 不要这样做在帮助文件中。
  • 是的,我明白了,但你为什么认为 NSDictionary 本身不足以完成这项任务?关于子类化的建议,请参阅NSDictionary reference page 中的“子类化说明”部分。
  • 哎呀...在完成我的作业后提出了一个经过深思熟虑的问题。
  • 同意没有(好的)理由 a) 子类 NSDictionary 或 b) 使其成为单例。作曲是通往这里的道路。即使是指向字典的全局指针也会更好。此外,子类化NSMutableDictionary 并不比NSDictionary 容易。其实我觉得还有更多个需要的方法。

标签: objective-c collections singleton nsdictionary subclassing


【解决方案1】:

为了避免子类化 NSDictionary 的麻烦,我将使用一个单独的单例对象,该对象使用组合来拥有一个 NSDictionary。不过,这是否可行取决于您希望对这个单例做什么。

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

【讨论】:

  • 我肯定会选择这个。子类化 NSDictionary 是完全没有必要的,在我遇到的每一种情况下
  • 我肯定对“你的单身人士长什么样?”入口!我在这里找到了一些关于作文的信息:developer.apple.com/library/mac/#documentation/General/…你还有其他喜欢的资源吗?谢谢。
  • 在这种情况下,实际上所有组合意味着您创建一个对象(单例),该对象具有自己的 ivar,用于 NSDictionary 具有您的真实数据。然后,您提供访问数据所需的任何方法,甚至提供对字典本身的访问,具体取决于您的用例。
  • 谢谢,我想我明白我的问题了。请参阅对原始问题的评论。
【解决方案2】:

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

从您的 cmets 看来,某些容器组合可能会为您提供很好的服务。很难从您的描述中准确说出您想要什么,因此我将不得不做出一些假设(我将尝试说明)并希望即使它们是错误的,您仍然可以指出正确的方向。因此,假设您有一个问题列表,并且对于每个问题,您都有一个答案和一些线索。在这种情况下,您可能会选择使用字典来表示每个问题。字典可以有三个键:“问题”、“答案”和“线索”。与前两个键关联的值可能只是字符串,而“线索”的值可能是一个数组或一组字符串。并且由于您有一些问题,您可以将这些字典中的每一个存储在一个公共数组中。在 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 的一个简单子类——数组和字典都是现成的。

【讨论】:

  • 谢谢,我想我明白我的问题了。请参阅对原始问题的评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-01
  • 2010-11-04
  • 2012-03-02
  • 1970-01-01
相关资源
最近更新 更多