天道酬勤,学无止境

Highly Performant Objective C Alternatives to the Switch Statement for Objects

I have a function which I would like to take in an NSString and an int arguments and then use the switch statement in order to return a calculated value, as in multiply the int by some constant, depending on what NSString is supplied.

Obviously, a switch statement doesn't work for objects in Objective-C. So what is the fastest alternative? Is it if-else statements? Or is there a more elegant method?

EDIT

The reason why I care about performance is that I am modifying UI elements the user is watching as the ultimate result of these calculations and I don't want that to feel sluggish.

评论

Don't optimize prematurely. Just make an NSDictionary that maps each string to its multiplier. Then see if that's fast enough.

If you need to do a different operation depending on the string, make each value in the dictionary a block that performs the appropriate operation.

The reason why I care about performance is that I am modifying UI elements the user is watching as the ultimate result of these calculations and I don't want that to feel sluggish.

So... you are doing a bunch of GUI operations that involve re-layout and re-drawing of a bunch of stuff and you are worried about the performance of an if/else statement?

Graphical operations in apps are huge consumers of CPU cycles. Orders of magnitude more cycles will be consumed during drawing in response to a graphical change compared to, say, a call to objectForKey: and a call to hash (which is what a dictionary lookup implies).

Measure your app's performance. Figure out why it is sluggish. Then fix the problem.

The first step would be to use the CPU sampling Instrument to see where those cycles are going.

If that doesn't help, use one of the various graphics perf analysis tools to see if that is your bottleneck.

It can also easily be that you are doing something multiple times that needs to be done only once; maybe your user interaction tracking code is causing the UI to be re-laid out multiple times when it only needs to be done once (I just fixed exactly this kind of performance problem in an app I'm working on).

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 使用Objective-C切换对象?(Objective-C switch using objects?)
    问题 我正在做一些Objective-C编程,其中涉及解析NSXmlDocument并从结果填充对象属性。 第一个版本如下所示: if([elementName compare:@"companyName"] == 0) [character setCorporationName:currentElementText]; else if([elementName compare:@"corporationID"] == 0) [character setCorporationID:currentElementText]; else if([elementName compare:@"name"] == 0) ... 但是我不喜欢这样产生的if-else-if-else模式。 查看switch语句,我看到我只能处理ints , chars等,而不能处理对象...所以有一个我不知道的更好的实现模式吗? 顺便说一句,我确实提出了一个更好的解决方案来设置对象的属性,但我想特别了解一下Objective-C中的if - else vs switch模式 回答1 我希望大家都原谅我的努力,但是我想解决在Cocoa中解析XML文档而不需要if-else语句的更普遍的问题。 最初指出的问题将当前元素文本分配给字符对象的实例变量。 正如jmah所指出的,这可以使用键值编码来解决。 但是
  • 目标c是IsKindOfClass的误会吗?(Objective c isKindOfClass missunderstanding?)
    问题 我有以下对象的结构: 动物,狗和猫。 如您所料,狗和猫是从动物继承而来的。 我有一个农场班: @implementation AnimalFarm -(Animal*) createAnimal:(AnimalType)type{ switch (type) { case CAT: return [Cat new]; case DOG: return [Dog new]; default: return [Animal new]; } } @end 我试图进行单元测试: AnimalFarm *farm = [AnimalFarm new]; Animal *dog = [farm createAnimal:DOG]; Animal *cat = [farm createAnimal:CAT]; STAssertTrue([cat isMemberOfClass:[Cat class]],@"cat is not a cat!"); STAssertTrue([dog isMemberOfClass:[Dog class]],@"Dog is not a dog!"); STAssertTrue([cat isKindOfClass:[Animal class]],@"Cat is not an animal!"); STAssertTrue([dog
  • Objective-C switch using objects?
    I'm doing some Objective-C programming that involves parsing an NSXmlDocument and populating an objects properties from the result. First version looked like this: if([elementName compare:@"companyName"] == 0) [character setCorporationName:currentElementText]; else if([elementName compare:@"corporationID"] == 0) [character setCorporationID:currentElementText]; else if([elementName compare:@"name"] == 0) ... But I don't like the if-else-if-else pattern this produces. Looking at the switch statement I see that i can only handle ints, chars etc and not objects... so is there a better
  • 使用Objective-c替代Ctags / Cscope吗?(Alternatives to Ctags/Cscope with Objective-c?)
    问题 具有Objective-c支持的ctags和cscope是否有替代方案? 这确实与可可粉的开发有关,因此不可避免地,我似乎将使用Xcode(可能应该使用)。 我只是想知道我的Vim选项是什么。 也许有某种类型的插件系统,例如eclim,但是对于xcode? 编辑 因此,除了更新ctags以支持Objective-C之外,我似乎很走运。 有人知道cscope是否相同吗? 回答1 这个问题(在vim上“玩”了很久之后),我希望获得ObjC支持,尤其是对于标签列表插件。 我找到了这个问题,然后进行了深入研究,这是一个不太肮脏的解决方案: 已将ObjectiveC解析器添加到Exuberant CTags干线中,但尚未发布(尚未?)。 您可以通过自制程序轻松地将其安装在OSX上: $ brew install ctags --HEAD 请注意,使用ctags时, .m被视为Matlab,而.h被视为C ++。 要覆盖,请使用: $ ctags --langmap=ObjectiveC:.mh 然后,我在.vimrc添加了类似的标签列表支持: let tlist_objc_settings = 'ObjectiveC;P:protocols;i:interfaces;types(...)' 从列表中添加您感兴趣的任何类型的内容: ctags --list-kinds=all
  • Objective-C 是否有等价于 java 的注解?(Does Objective-C have an equivalent to java annotations?)
    问题 Objective-C 是否有等价于 java 的注解? 我想要做的是创建一个属性并能够以某种方式访问​​有关它的一些元数据。 我希望能够确定我的数组中应该包含什么类型的类,所以我想以某种方式对其进行注释以这样说。 然后可以通过诸如运行时库之类的东西访问该注释,我可以在其中访问属性列表及其名称。 //Put some sort of annotation giving a class name. @property (strong) NSArray *myArray; 回答1 你说: 我希望能够确定我的数组中应该包含什么类型的类,所以我想以某种方式对其进行注释以这样说。 然后可以通过诸如运行时库之类的东西访问该注释,我可以在其中访问属性列表及其名称。 在 Objective-C 中有几种方法可以做这种事情。 Apple 的框架通过添加一个返回所需信息的类方法来完成这类事情。 示例:KVO 中的依赖键、+[CALayer needsDisplayForKey:] 和相关方法。 因此,让我们创建一个类方法,该方法根据属性名称返回可以进入容器属性的类数组。 首先,我们将向NSObject添加一个类别以实现该方法的通用版本: @interface NSObject (allowedClassesForContainerProperty) + (NSArray *
  • 如何在开关中使用null(How to use null in switch)
    问题 Integer i = ... switch (i){ case null: doSomething0(); break; } 在上面的代码中,我不能在switch case语句中使用null。 我该怎么做呢? 我不能使用default因为那样的话我还想做其他事情。 回答1 对于Java中的switch语句,这是不可能的。 switch前检查是否为null : if (i == null) { doSomething0(); } else { switch (i) { case 1: // ... break; } } 您不能在switch语句*中使用任意对象。 编译器不抱怨i是Integer switch (i)原因是因为Java自动将Integer拆箱为int 。 正如assylias所说,当i为null时,拆箱将抛出NullPointerException 。 *从Java 7开始,您可以在switch语句中使用String 。 有关Oracle Docs中的switch (包括带有null变量的示例)的更多信息-Switch 回答2 switch ((i != null) ? i : DEFAULT_VALUE) { //... } 回答3 如果i为null , switch(i)将抛出NullPointerException,因为它将尝试将Integer拆箱为int
  • 当前的功能性反应式编程实现的状态如何?(What's the status of current Functional Reactive Programming implementations?)
    问题 我正在尝试可视化Haskell中的一些简单的自动物理系统(如摆锤,机器人手臂等)。 通常,这些系统可以用以下等式来描述 df/dt = c*f(t) + u(t) 其中u(t)代表某种“智能控制”。 这些系统看起来非常适合于功能性反应式编程范例。 因此,我抓住了Paul Hudak的《 Haskell表达学校》一书,发现那里介绍的领域特定语言“ FAL”(用于功能动画语言)实际上对我的简单玩具系统非常令人满意(尽管某些功能特别是integrate ,对于有效使用而言似乎有点太懒了,但很容易修复)。 我的问题是,对于当今更高级甚至是实际的应用程序,最成熟,最新,维护良好,性能调整的替代方案是什么? 该Wiki页面列出了Haskell的几个选项,但是我不清楚以下方面: Conal Eliott的项目(据我所知)是这种编程范例的发明者之一,它的“反应性”状态看起来有些陈旧。 我喜欢他的代码,但也许我应该尝试其他最新的替代方法? 就语法/性能/运行时稳定性而言,它们之间的主要区别是什么? 引用2011年的一项调查中的第6节,“ ... FRP实施的性能仍然不够高效或可预测,无法在需要延迟保证的域中有效使用... ”。 鉴于调查结果表明FRP存在超过15年的事实,该调查提出了一些有趣的可能的优化方案,我给人的印象是,至少在几年内,此性能问题可能非常或什至固有地很难解决。 这是真的?
  • 我可以在Objective-C switch语句中声明变量吗?(Can I declare variables inside an Objective-C switch statement?)
    问题 我想我快要瞎了,因为我无法弄清楚这段代码中的语法错误在哪里: if( cell == nil ) { titledCell = [ [ [ TitledCell alloc ] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier ] autorelease ]; switch( cellNumber ) { case 1: NSString *viewDataKey = @"Name"; etc... 当我尝试对其进行编译时,在最后一行的'*'标记之前收到一个Error:语法错误。 很抱歉有这样一个基本问题,但是我想念的是什么? 回答1 我手边没有合适的Objective-C编译器,但只要C构造相同即可: switch { … }给您一个块级范围,而不是每种case 。 在范围的开头以外的任何地方声明变量都是非法的,并且在switch内部尤为危险,因为它的初始化可能会被跳过。 以下任一方法是否可以解决问题? NSString *viewDataKey; switch (cellNumber) { case 1: viewDataKey = @"Name"; … } switch (cellNumber) { case 1: { NSString *viewDataKey = @"Name"; … } … } 回答2
  • 在switch语句中使用NSString(Using an NSString in a switch statement)
    问题 是否可以在switch语句中使用NSString ? 还是只使用if / else if更好? 回答1 switch语句在这种情况下需要整数常量,因此此处无法使用NSString,因此似乎必须使用if / else选项。 还有一点是,您必须使用isEqualToString:或compare:方法比较NSString,因此,即使在切换情况下允许使用指针值,也无论如何也不能使用它们 回答2 我在应用程序中使用这些宏。 #define CASE(str) if ([__s__ isEqualToString:(str)]) #define SWITCH(s) for (NSString *__s__ = (s); ; ) #define DEFAULT SWITCH (string) { CASE (@"AAA") { break; } CASE (@"BBB") { break; } CASE (@"CCC") { break; } DEFAULT { break; } } 回答3 作为回应,并支持@Cœur的回答。这是同一件事,但是用Xcode 4.4+ / clang /编写,无论哪种“文字语法”都更接近于简单的泌尿系统if, else进行比较(这就是重点,不是它.....) NSDictionary *actionD = @{ @"A" : ^{ NSLog(@
  • 动态绑定或开关/案例?(dynamical binding or switch/case?)
    问题 这样的场景: 我有不同的对象执行与各自的func()实现类似的操作。 func_manager()根据不同的对象调用func()有两种解决方案 解决方案1 :使用c ++中指定的虚拟函数字符。 func_manager对不同的对象点传入具有不同的作用。 class Object{ virtual void func() = 0; } class Object_A : public Object{ void func() {}; } class Object_B : public Object{ void func() {}; } void func_manager(Object* a) { a->func(); } 解决方案2 :使用普通开关/盒。 func_manager的工作方式不同,适用于不同类型的传入 typedef enum _type_t { TYPE_A, TYPE_B }type_t; void func_by_a() { // do as func() in Object_A } void func_by_b() { // do as func() in Object_A } void func_manager(type_t type) { switch(type){ case TYPE_A: func_by_a(); break; case TYPE_B
  • 处理枚举时无默认值的switch语句(Switch statement without default when dealing with enumerations)
    问题 自从我开始使用.NET以来,这一直是我的宠儿,但我很想知道自己是否缺少某些东西。 我的代码段无法编译(请原谅示例的强制性质),因为(根据编译器)缺少return语句: public enum Decision { Yes, No} public class Test { public string GetDecision(Decision decision) { switch (decision) { case Decision.Yes: return "Yes, that's my decision"; case Decision.No: return "No, that's my decision"; } } } 现在我知道我可以简单地放置一个默认语句来摆脱编译器警告,但是在我看来,不仅是冗余代码,而且是危险代码。 如果枚举在另一个文件中,并且另一个开发人员出现并将Maybe添加到我的枚举中,则它将由我的默认子句处理,该子句对Maybe一无所知,我们很有可能引入逻辑错误。 而如果编译器允许我使用上面的代码,则它可以确定我们有问题,因为我的case语句将不再涵盖枚举中的所有值。 当然,这对我来说更安全。 这从根本上来说对我来说是错误的,我想知道这是否只是我所缺少的东西,还是在switch语句中使用枚举时我们是否必须非常小心? 编辑:我知道我可以在默认情况下引发异常
  • 在学习Objective-C之前先学习C(Learn C first before learning Objective-C [closed])
    问题 从目前的情况来看,这个问题不适合我们的问答形式。 我们希望答案得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意测验或进一步的讨论。 如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 9年前关闭。 作为一名有抱负的Apple开发人员,如果要在进入Objective-C并最终进入Cocoa Framework之前先学习C更好,那么我想征询社区的意见。 我的直觉说学习C,这将为我奠定良好的基础。 回答1 我会先学习C。 在转到Obj-C之前,我学习了C(并且在C中做了很多事情)。 我有很多同事,他们从来都不是真正的C程序员,他们从Obj-C开始,只学习了必要的C语言。 我时不时地看到他们如何完全在Obj-C中解决问题,有时会导致非常笨拙的解决方案。 通常,然后我用纯C代码替换一些Obj-C代码(毕竟,您可以随意混合它们,Obj-C方法的内容可以完全是纯C代码)。 没有任何侮辱任何Obj-C程序员的意图,Obj-C中有一些非常优雅的解决方案,这些解决方案由于对象的原因而变得更好用(并且看起来更好)(OOP编程可以使复杂程序变得比可爱得多)。函数编程;例如,多态是一个出色的功能)……我真的很喜欢Obj-C(比C ++还要多!我讨厌C ++语法,并且某些语言功能过于简单,会导致不良的开发模式恕我直言); 但是,当我有时重新编写同事的Obj
  • 【GCC】gcc警告选项汇总--编辑中
    参考原文:https://blog.csdn.net/qq_17308321/article/details/79979514 前言 警告:不是错误的,但是有风险或表明可能有错误。 请求或取消警告选项 (https://blog.csdn.net/qq_17308321/article/details/79979514) -fsyntax-only 检查代码中的语法错误,但除此之外不要做任何事情。 -w 禁止所有警告消息。 -Werror 使所有的警告进入错误。 -Werror= 将指定的警告转换为错误。 请注意,指定-Werror = foo会自动隐含-W foo 。 但是, -Wno-error = foo并不意味着什么。 -Wfatal-errors 在发生第一个错误时中止编译。 请求和关闭告警方式 以“ -W ”请求特定的警告 - 可以隐式地请求隐式声明的警告。 以“ -Wno- ”开头关闭特定的警告; $ gcc -Wall -Wno-unused test.c -o test 连带开启 某些选项(如-Wall和-Wextra )会打开其他选项,例如-Wunused ,这可能会启用其他选项,例如-Wunused-value 。 作用顺序和覆盖 具体的选项优先于不特定的选项,与命令行中的位置无关。 对于相同特征的选项,最后一个生效。 -Wall (http://blog
  • switch statement in C / Objective C
    I am new to Objective-C, But from all I know about switch statements, the following code should not print anything, because to me it seems that there should be a compilation error. However 2 is printed. I do not understand why. Could someone please explain? - (void) test { int myVar = 2; switch (myVar) { case 1: { NSLog(@"result: %d", myVar); break; case 2: { NSLog(@"result: %d", myVar); } break; } } }
  • Alternative to switch statement in objective C
    I am doing a project in which I am loading a table view with JSON data from an asynchronous connection. I am using a switch statement to load each row, like so: dictionaryData = [responseString JSONValue]; switch (indexPath.row) { case 0: { NSString *name = [NSString stringWithFormat:@"%@ : %@ %@",@"Name",[dictionaryData valueForKey:@"firstName"],[dictionaryData valueForKey:@"lastName"]]; cell.textLabel.text = name; break; } case 1: { NSString *email = [NSString stringWithFormat:@"%@ : %@",@"Email",[dictionaryData valueForKey:@"email"]]; cell.textLabel.text = email; } break; There are 8 rows
  • 在目标 c 中切换 NSString 的大小写 [重复](switch case on NSString in objective c [duplicate])
    问题 这个问题在这里已经有了答案: 在 switch 语句中使用 NSString (9 个回答) 7年前关闭。 我想在 NSString 中使用 case 语句,请将我的代码更改为正确的代码 NSString *day = @"Wed"; switch (day) { case @"Sat": NSlog(@"Somthing..."); break; case @"Sun": NSlog(@"Somthing else..."); break; . . . . default: break; } 回答1 如果你想要一些比一长串条件更智能的调度,你可以使用块字典: NSString *key = @"foo"; void (^selectedCase)() = @{ @"foo" : ^{ NSLog(@"foo"); }, @"bar" : ^{ NSLog(@"bar"); }, @"baz" : ^{ NSLog(@"baz"); }, }[key]; if (selectedCase != nil) selectedCase(); 如果您有很长的案例列表并且经常这样做,那么这可能会带来很小的性能优势。 你应该缓存字典,然后(不要忘记复制块)。 为了方便和简洁而牺牲易读性,这是一个将所有内容放入单个语句并添加默认情况的版本: ((void (^)())@{ @"foo"
  • 有没有办法将变量绑定到switch语句中的多个替代项?(Is there a way to bind a variable to multiple alternatives in a switch statement?)
    问题 假设我有一个枚举定义,如下所示: enum Response { case Result(String, Int) case Error(String) } 然后,我得到这样的回应: let resp: Response = // ... 假设我想编写一个switch语句,并以相同的方式处理Result和Error情况,并将相同名称的变量绑定到它们包含的String中。 我怎样才能做到这一点? 从概念上讲,类似于以下内容: switch resp { case let .Result(str, _), let .Error(str): println("Found: \(str)") } 其中str被绑定两次,并且_表示我对Result携带的Int值不感兴趣。 到目前为止,我能找到的最接近的东西是这样声明一个内联函数,然后调用它: func processRespString(str: String) { println("Found \(str)") } switch resp { case let .Result(str, _): processRespString(str) case let .Error(str): processRespString(str) } 有没有更好的办法? 回答1 已接受的Swift进化提案SE-0043已通过Swift 3修复了此问题。
  • Is there a way to bind a variable to multiple alternatives in a switch statement?
    Suppose I have an enum definition as follows: enum Response { case Result(String, Int) case Error(String) } Then, I get such a response: let resp: Response = // ... Suppose I want to write a switch statement and handle the same way the Result and the Error cases and bind a variable of the same name to the String they contain. How can I do this? Conceptually, something similar to this: switch resp { case let .Result(str, _), let .Error(str): println("Found: \(str)") } where str is bound twice, and _ signals that I'm not interested in the Int value that a Result carries. So far, the closest
  • Obj-C中的怪异开关错误(Weird Switch error in Obj-C)
    问题 我的代码中有以下switch语句: switch(buttonIndex){ case 0: [actionSheet dismissWithClickedButtonIndex:buttonIndex animated:YES]; break; case 1: UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init]; imagePicker.delegate = self; imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera; [self presentModalViewController:[imagePicker autorelease] animated:YES]; break; default: [self openEmailViewInViewController:self]; } 在案例1的UIImagePickerController实例中,我得到一个错误: error:expected expression before 'UIImagePickerController' 而且我不知道我在做什么错。 有什么想法吗? 哦,buttonIndex是一个NSInteger 回答1
  • 在Objective-C中确定属性是否为int,float,double,NSString,NSDate,NSNumber等(In Objective-C Determine if a Property is an int, float, double, NSString, NSDate, NSNumber, etc)
    问题 为了从XML执行反序列化,我需要确定对象的属性(按名称传递)类型。 我有一些通用的伪代码(但是我不确定如何在Objective-C中执行这些比较): id object = [[[Record alloc] init] autorelease]; NSString *element = @"date"; NSString *data = @"2010-10-16"; objc_property_t property = class_getProperty([object class], [element UTF8String]); const char *attributes = property_getAttributes(property); char buffer[strlen(attributes) + 1]; strcpy(buffer, attributes); char *attribute = strtok(buffer, ","); if (*attribute == 'T') attribute++; else attribute = NULL; if (attribute == NULL); else if (strcmp(attribute, "@\"NSDate\"") == 0) [object setValue:[NSDate