Objective c 静态字符串->字符串映射

Objective c 静态字符串->字符串映射,objective-c,cocoa-touch,cocoa,mapping,Objective C,Cocoa Touch,Cocoa,Mapping,我需要一个字符串->字符串映射在运行时使用,除非映射在构建后永远不会更改 天真的解决方案是只使用NSDictionary,但必须有一种更优化的方法来实现这一点,不是吗 从某种意义上说,如果映射在编译时已知,并且已知永远不会更改,那么编译器应该能够在编译时进行映射。NSDictionary需要在运行时执行哈希查找。我知道这是固定的时间,但我觉得它有点不干净…你可以硬编码你的NSDictionary,如果不太麻烦的话,也就是说,它不是很大,或者你可以创建一个plist并将其包含在你的应用包中。然后,

我需要一个字符串->字符串映射在运行时使用,除非映射在构建后永远不会更改

天真的解决方案是只使用NSDictionary,但必须有一种更优化的方法来实现这一点,不是吗

从某种意义上说,如果映射在编译时已知,并且已知永远不会更改,那么编译器应该能够在编译时进行映射。NSDictionary需要在运行时执行哈希查找。我知道这是固定的时间,但我觉得它有点不干净…

你可以硬编码你的NSDictionary,如果不太麻烦的话,也就是说,它不是很大,或者你可以创建一个plist并将其包含在你的应用包中。然后,在应用程序启动时,从plist中阅读字典并输入几行代码。这些方法中的每一种都是同样的努力。使用plist的好处是,如果您必须更改它,您可以编辑plist,而不是编码。

如果不太麻烦,也就是说,不太庞大,您可以硬编码NSDictionary,或者您可以创建一个plist并将其包含在您的应用程序包中。然后,在应用程序启动时,从plist中阅读字典并输入几行代码。这些方法中的每一种都是同样的努力。使用plist的优点是,如果您必须更改它,您是在编辑plist,而不是代码。

静态NSDictionary是正确的工具。通常使用+initialize方法初始化这些参数:

在对该类调用第一个请求的方法之前,在线程安全的情况下,每个类调用一次initialize,通常第一个方法是+alloc。自检是因为子类将自动调用它们的[super initialize],在这种情况下,您通常不希望多次运行它。

静态NSDictionary是正确的工具。通常使用+initialize方法初始化这些参数:


在对该类调用第一个请求的方法之前,在线程安全的情况下,每个类调用一次initialize,通常第一个方法是+alloc。自检是因为子类将自动调用它们的[super initialize],在这种情况下,您通常不希望多次运行它。

在什么意义上更优化?您是否发现NSDictionary存在性能问题,或者您只是假设一定存在性能问题?更新了我的问题,以澄清我所说的“最优”是什么意思。如果要按照您的第一句话在运行时使用映射,编译器如何在编译时进行映射?你能解释一下你要解决的问题吗?我想是枚举之类的。也许我解释错了,但我想在仔细考虑之后能够做的是将字符串映射到枚举的一个成员。我不确定这是否可能…在什么意义上更优化?您是否发现NSDictionary存在性能问题,或者您只是假设一定存在性能问题?更新了我的问题,以澄清我所说的“最优”是什么意思。如果要按照您的第一句话在运行时使用映射,编译器如何在编译时进行映射?你能解释一下你要解决的问题吗?我想是枚举之类的。也许我解释错了,但我想在仔细考虑之后能够做的是将字符串映射到枚举的一个成员。我不确定这是否可能…是否有任何理由不使用dispatch_once guard来代替初始化?这似乎更符合预期的限制,并且如果在这个类之前使用了其中一个子类,它将允许子类确保字典可用?您可以将它放在init中,但是如果该对象是使用initWithCoder创建的呢?如果有依赖于字典的类方法,而字典可能在第一次初始化之前被调用,该怎么办+initialize处理所有这些极端情况,因此避免了微妙和困难的bug。在实例方法中进行类初始化是不好的。如果你在一个类方法中这样做,为什么不在正确的时间自动调用+initialize呢。对不起,我的意思是用dispatch_替换if self==[MYClass],inside+initialize,而不是将字典创建移到别处。然后,在继承树中以这个类开始的任何类的第一条消息都将创建字典,其他任何类都不会重新创建字典。是吗?派一次就可以了+initialize比GCD早得多,类检查是传统的模式。dispatch_once是一行额外的代码,但它的优点是不需要硬编码类名。我们在ObjC中做了一些事情,因为从下一步开始就是这样做的;这并不意味着我们不应该每隔几年就重新考虑一次……我就是这么想的。谢谢你的澄清。从OSX Puma开始,我才开始使用ObjC——这种语言在过去发展得很快
几年!是否有任何理由不使用dispatch_once guard来代替初始化?这似乎更符合预期的限制,并且如果在这个类之前使用了其中一个子类,它将允许子类确保字典可用?您可以将它放在init中,但是如果该对象是使用initWithCoder创建的呢?如果有依赖于字典的类方法,而字典可能在第一次初始化之前被调用,该怎么办+initialize处理所有这些极端情况,因此避免了微妙和困难的bug。在实例方法中进行类初始化是不好的。如果你在一个类方法中这样做,为什么不在正确的时间自动调用+initialize呢。对不起,我的意思是用dispatch_替换if self==[MYClass],inside+initialize,而不是将字典创建移到别处。然后,在继承树中以这个类开始的任何类的第一条消息都将创建字典,其他任何类都不会重新创建字典。是吗?派一次就可以了+initialize比GCD早得多,类检查是传统的模式。dispatch_once是一行额外的代码,但它的优点是不需要硬编码类名。我们在ObjC中做了一些事情,因为从下一步开始就是这样做的;这并不意味着我们不应该每隔几年就重新考虑一次……我就是这么想的。谢谢你的澄清。从OSX Puma开始,我才开始使用ObjC——在过去的几年里,这种语言发展得很快!这是我过去经常做的事。然而,它仍然让我感觉脏兮兮的,因为您正在为编译时完全已知的东西进行运行时计算!如果plist很大,运行时的影响可能很大。但有办法将这种处理推到后台,并减轻任何明显的滞后。另一方面,您希望维护什么:代码还是plist?这里的答案在某种程度上取决于数据的性质和大小。马克,你说得对。我同意保持PLIST是可取的,但这种情况下的数据量很小。然而,为了简单易读,我可能会选择PLISt路线。这是我过去经常使用的方法。然而,它仍然让我感觉脏兮兮的,因为您正在为编译时完全已知的东西进行运行时计算!如果plist很大,运行时的影响可能很大。但有办法将这种处理推到后台,并减轻任何明显的滞后。另一方面,您希望维护什么:代码还是plist?这里的答案在某种程度上取决于数据的性质和大小。马克,你说得对。我同意保持PLIST是可取的,但这种情况下的数据量很小。然而,为了简单易读,我可能最终会选择PLISt路线。
static NSDictionary *kDictionary;

+ (void)initialize {
  if (self == [MYClass class]) {
    kDictionary = [[NSDictionary alloc] initWith...];
  }
}