【发布时间】:2011-09-01 18:07:06
【问题描述】:
我决定尝试在 Objective-C 中使用块进行控制流,但在调用多个内联块时遇到了一些问题。
我有一个 OOBoolean,它是 BOOL 原语的包装器,并提供以下方法:
+ (id) booleanWithBool: (BOOL) boolPrimitive;
- (id) initWithBool: (BOOL) boolPrimitive;
- (void) ifTrueDo: (void (^) ()) trueBlock
ifFalseDo: (void (^) ()) falseBlock;
- (void) ifTrueDo: (void (^) ()) trueBlock;
- (void) ifFalseDo: (void (^) ()) falseBlock;
像这样使用这个类没有问题:
OOBoolean* condition = [OOBoolean booleanWithBool: (1 + 1 == 2)];
id trueBlock = ^(){
NSLog(@"True.");
};
id falseBlock = ^(){
NSLog(@"False.");
};
[condition ifTrueDo: trueBlock ifFalseDo: falseBlock];
我得到“真”的结果。但是在尝试此操作时,我不断收到语法错误:
OOBoolean* condition = [OOBoolean booleanWithBool: (1 + 1 == 2)];
[condition ifTrueDo:(void (^)()) {
NSLog(@"True");
} ifFalseDo:(void (^)()) {
NSLog(@"False");
}];
难道不能匿名定义多个块并将它们传递给一个接受多个块参数的方法吗?如果是这样,那就有点令人失望了。
【问题讨论】:
-
有趣的想法,虽然我认为这在运行时比让编译器为您优化条件要低得多。
-
我实际上有兴趣了解这里的效率差异。显然,由于额外的消息发送,效率较低,而且我知道在 ifTrue ifFalse 消息调用之外有一些块和封闭变量的性能考虑,但我很好奇这会产生多大的影响。
-
考虑这一点的最简单方法是考虑您要推送的堆栈帧数。您拥有的堆栈帧越多,您的代码效率就越低(可能)。我不太了解编译器理论,但我可以猜测使用标准
if() else构造会在编译时使用某些选项优化程序流程。 -
您是否熟悉其他类似的语言?你知道这些是否有类似的性能惩罚?我正在专门考虑 Smalltalk,但我想知道是否也可以针对这种格式进行编译器优化(我想它们必须在 Smalltalk 之类的东西中,因为它是进行控制流的唯一方法)。我不得不承认我对实现问题也很无知,我只是喜欢这种风格。
-
我不能对 Smalltalk 发表评论(我知道你会提到 Smalltalk)但是任何值得一提的编译器都知道如何识别代码中的热点和常见的决策结构优化,就像展开循环一样。恕我直言,我认为 Objective C 编译器将无法优化您的 OOBolean 类行为。
标签: objective-c ios objective-c-blocks