iphoneos:制作一个switch语句,使用字符串文本作为比较器,而不是整数
所以我想这样做:iphoneos:制作一个switch语句,使用字符串文本作为比较器,而不是整数,iphone,objective-c,switch-statement,string-comparison,Iphone,Objective C,Switch Statement,String Comparison,所以我想这样做: switch (keyPath) { case @"refreshCount": //do stuff case @"timesLaunched": //do other stuff } 但显然,你只能用整数作为开关量。这样做的唯一方法是将字符串解析为整数标识符,然后运行switch语句吗 像这样: nsinteger num = nil; if (keyPath isEqual:@"refreshCount") { num
switch (keyPath) {
case @"refreshCount":
//do stuff
case @"timesLaunched":
//do other stuff
}
但显然,你只能用整数作为开关量。这样做的唯一方法是将字符串解析为整数标识符,然后运行switch语句吗
像这样:
nsinteger num = nil;
if (keyPath isEqual:@"refreshCount") {
num = 0
}
if (keyPath isEqual:@"timesLaunched") {
num = 1
}
if ([keyPath isEqual:@"refreshCount"] && ([[change valueForKey:@"new"] intValue] == 10)) { //
NSLog(@"achievemnt hit inside");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"title" message:@"Achievement Unlocked!" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:nil];
[alert show];
我正在尽可能快地优化这段代码,因为它会经常被调用
谢谢
尼克
注意:是的,我正在使用KVO,所以我在“回调”中收到一个字符串
注释2:所以我首先考虑的是Switter语句,我原来的代码实现是这样的:
nsinteger num = nil;
if (keyPath isEqual:@"refreshCount") {
num = 0
}
if (keyPath isEqual:@"timesLaunched") {
num = 1
}
if ([keyPath isEqual:@"refreshCount"] && ([[change valueForKey:@"new"] intValue] == 10)) { //
NSLog(@"achievemnt hit inside");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"title" message:@"Achievement Unlocked!" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:nil];
[alert show];
我想用相同的方法,用不同的XX值做一系列这些:
if ([keyPath isEqual:@"refreshCount"] && ([[change valueForKey:@"new"] intValue] == 10)) {
//unlock small achievement
}
if ([keyPath isEqual:@"refreshCount"] && ([[change valueForKey:@"new"] intValue] == 50)) {
//unlock bigger achievement
}
//etc
这对我来说似乎效率很低,但也许我错了。为什么不使用枚举
typedef enum _KeyPath
{
KeyPathNone,
KeyPathRefreshCount,
KeyPathTimesLaunched,
KeyPathCount
} KeyPath;
如果必须使用应与之比较的字符串,请使用IsequalString:
从NSString文档:
Special Considerations
When you know both objects are strings, this method is a faster way to check equality than isEqual:.
简而言之,首先不要使用字符串。除此之外,您可以让字符串成为具有整数(NSNumber)值的字典中的键。或者可以使用字符串的哈希
switch ( [keyPath myQuickHash] ) {
case kHashRefreshCount:
case kHashTimesLaunched:
}
如果只有几个不同的字符串,则可以使用第一个(或最后一个)4个字符作为字符串文字,并考虑哈希.< /P>
switch ( [keyPath stringLiteral] ) {
case 'refr':
case 'time':
}
编辑:
switch语句本质上是一个稀疏的代码片段数组。哈希表是一种在给定任意值的稀疏数组中查找索引的方法。给定一组已知的字符串输入,switch语句可以像哈希表一样运行,也就是说,具有恒定的查找时间。您所要做的就是为已知输入选择一个没有冲突的哈希算法。如果输入集未知,则这不是一个选项,但在这个问题中,所有输入都可能已知
这与苹果如何实现他们的哈希算法完全无关,因为你必须实现自己的哈希算法。所选择的算法可能很简单,只需将字符串中的长度和字母相加即可。也就是说,要使cast语句正常工作,它只需调用
isEqualToString:
即可,速度可能与您想象的一样慢,但速度可能不会太慢
当然,第一个问题是您是否衡量了性能,是否有证据表明代码导致了性能问题?
如果没有,就去完成你的应用程序。发货应用程序总是比仍在开发中的应用程序表现更好
我敢打赌你没有性能问题;如果您的所有字符串都是与键值观察相关的内联字符串常量--“refreshCount”等,那么很可能所有字符串都是编译到应用程序中的常量字符串,因此比较会非常快,因为每次您提到“@refreshCount”
它实际上是同一地址的同一字符串(比较起来非常快)
如果您确实存在可量化的性能问题,请在不同的问题中发布详细信息,有人可以具体回答。实际上,除了推测之外,没有足够的体系结构或定量信息来做任何事情。很可能是因为他使用的是KVO或KVC,因此需要将路径作为NSString。是的,我使用的是KVO,所以我要将字符串发回,请参阅问题中添加的注释。在这种情况下,请使用
IsequalString:
方法,避免使用组条件,因为它会反复计算条件的第一部分。而是使用嵌套的条件。如果一个大的成就只能在一个小的成就之后才能实现,那么只需让你的成就授予逻辑反映这一事实。你可能不想使用哈希,因为一个非常小但非零的冲突机会可能会导致奇怪的错误。enum
可能更干净、更安全。哈希运算速度较慢。非常非常慢。如果我们讨论的是5个不同的键,它们都是常量NSString,那么直接级联If(…IsequalString:…)
测试很可能会更快。将-hash
与常量进行比较是行不通的。对象的散列
仅在运行时是常量。使用子字符串操作可能更快,也可能更快——这取决于字符串集。哈希值应该在编译时计算。如果发生碰撞,将选择不同的算法。散列的速度将与对isEqualToString的单个调用的速度相同,除非您认为这需要加密散列。@bbum散列的要点是相等的输入产生相等的输出。编译时和运行时之间有什么变化?你是对的,我没有编写代码来查看是否有问题,我只是坐下来开始编写switch语句,当时我想完全实现这个方法,因为我认为它会更有效率。顺便说一句:“一个发货应用总是比一个仍在开发中的应用表现更好!”真是太棒了!谢谢你。我正在添加另一条关于我最初实现的注释,这让我首先对效率提出了质疑。欢迎您。这是一个好问题,有几个原因;字符串操作会扼杀性能&根据常量字符串实现,实现比人们想象的更微妙。